15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/custom_home_pages_table_model.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/history/history_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/table_model_observer.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks whether the given URL should count as one of the "current" pages. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true for all pages except dev tools and settings. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldAddPage(const GURL& url) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.is_empty()) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (url.SchemeIs(content::kChromeDevToolsScheme)) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (url.SchemeIs(content::kChromeUIScheme)) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.host() == chrome::kChromeUISettingsHost) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For a settings page, the path will start with "/settings" not "settings" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so find() will return 1, not 0. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.host() == chrome::kChromeUIUberHost && 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.path().find(chrome::kChromeUISettingsHost) == 1) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CustomHomePagesTableModel::Entry { 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Entry() : task_id(base::CancelableTaskTracker::kBadTaskId) {} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URL of the page. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Page title. If this is empty, we'll display the URL as the entry. 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If not |base::CancelableTaskTracker::kBadTaskId|, indicates we're loading 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the title for the page. 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::CancelableTaskTracker::TaskId task_id; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CustomHomePagesTableModel::CustomHomePagesTableModel(Profile* profile) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_(NULL) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CustomHomePagesTableModel::~CustomHomePagesTableModel() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::SetURLs(const std::vector<GURL>& urls) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.resize(urls.size()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < urls.size(); ++i) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[i].url = urls[i]; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[i].title.erase(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadTitle(&(entries_[i])); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Complete change, so tell the view to just rebuild itself. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnModelChanged(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Move a number of existing entries to a new position, reordering the table. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We determine the range of elements affected by the move, save the moved 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * elements, compact the remaining ones, and re-insert moved elements. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Expects |index_list| to be ordered ascending. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::MoveURLs(int insert_before, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int>& index_list) { 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (index_list.empty()) return; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(insert_before >= 0 && insert_before <= RowCount()); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The range of elements that needs to be reshuffled is [ |first|, |last| ). 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int first = std::min(insert_before, index_list.front()); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last = std::max(insert_before, index_list.back() + 1); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the dragged elements. Also, adjust insertion point if it is before a 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dragged element. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Entry> moved_entries; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < index_list.size(); ++i) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) moved_entries.push_back(entries_[index_list[i]]); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index_list[i] == insert_before) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert_before++; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compact the range between beginning and insertion point, moving downwards. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t skip_count = 0; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = first; i < insert_before; ++i) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skip_count < index_list.size() && index_list[skip_count] == i) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_count++; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entries_[i - skip_count] = entries_[i]; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moving items down created a gap. We start compacting up after it. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first = insert_before; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert_before -= skip_count; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now compact up for elements after the insertion point. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_count = 0; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = last - 1; i >= first; --i) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skip_count < index_list.size() && 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index_list[index_list.size() - skip_count - 1] == i) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_count++; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[i + skip_count] = entries_[i]; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Insert moved elements. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(moved_entries.begin(), moved_entries.end(), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.begin() + insert_before); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Possibly large change, so tell the view to just rebuild itself. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnModelChanged(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::Add(int index, const GURL& url) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index <= RowCount()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.insert(entries_.begin() + static_cast<size_t>(index), Entry()); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[index].url = url; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadTitle(&(entries_[index])); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnItemsAdded(index, 1); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::Remove(int index) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index < RowCount()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry* entry = &(entries_[index]); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel any pending load requests now so we don't deref a bogus pointer when 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we get the loaded notification. 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (entry->task_id != base::CancelableTaskTracker::kBadTaskId) { 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) task_tracker_.TryCancel(entry->task_id); 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry->task_id = base::CancelableTaskTracker::kBadTaskId; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.erase(entries_.begin() + static_cast<size_t>(index)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnItemsRemoved(index, 1); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::SetToCurrentlyOpenPages() { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the current entries. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (RowCount()) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Remove(0); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And add all tabs for all open browsers with our profile. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_index = 0; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = *it; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser->profile() != profile_) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Skip incognito browsers. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int tab_index = 0; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_index < browser->tab_strip_model()->count(); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++tab_index) { 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL url = 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetWebContentsAt(tab_index)->GetURL(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldAddPage(url)) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Add(add_index++, url); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<GURL> CustomHomePagesTableModel::GetURLs() { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> urls(entries_.size()); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < entries_.size(); ++i) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls[i] = entries_[i].url; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return urls; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CustomHomePagesTableModel::RowCount() { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(entries_.size()); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 CustomHomePagesTableModel::GetText(int row, int column_id) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(column_id == 0); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(row >= 0 && row < RowCount()); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entries_[row].title.empty() ? FormattedURL(row) : entries_[row].title; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 CustomHomePagesTableModel::GetTooltip(int row) { 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return entries_[row].title.empty() ? base::string16() : 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16(IDS_OPTIONS_STARTUP_PAGE_TOOLTIP, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[row].title, FormattedURL(row)); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::SetObserver(ui::TableModelObserver* observer) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_ = observer; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::LoadTitle(Entry* entry) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService* history_service = HistoryServiceFactory::GetForProfile( 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_, Profile::EXPLICIT_ACCESS); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service) { 226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry->task_id = history_service->QueryURL( 227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry->url, 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) false, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CustomHomePagesTableModel::OnGotTitle, 230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this), 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry->url), 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &task_tracker_); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void CustomHomePagesTableModel::OnGotTitle(const GURL& entry_url, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found_url, 238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const history::URLRow& row, 239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const history::VisitVector& visits) { 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Entry* entry = NULL; 241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t entry_index = 0; 242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t i = 0; i < entries_.size(); ++i) { 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (entries_[i].url == entry_url) { 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry = &entries_[i]; 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry_index = i; 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The URLs changed before we were called back. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry->task_id = base::CancelableTaskTracker::kBadTaskId; 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (found_url && !row.title().empty()) { 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) entry->title = row.title(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnItemsChanged(static_cast<int>(entry_index), 1); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 CustomHomePagesTableModel::FormattedURL(int row) const { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string languages = 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); 264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 url = net::FormatUrl(entries_[row].url, languages); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = base::i18n::GetDisplayStringInLTRDirectionality(url); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 268