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" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.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) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.SchemeIs(chrome::kChromeDevToolsScheme)) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.SchemeIs(chrome::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 { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry() : title_handle(0) {} 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) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If non-zero, indicates we're loading the title for the page. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService::Handle title_handle; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CustomHomePagesTableModel::CustomHomePagesTableModel(Profile* profile) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_(NULL) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CustomHomePagesTableModel::~CustomHomePagesTableModel() { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::SetURLs(const std::vector<GURL>& urls) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.resize(urls.size()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < urls.size(); ++i) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[i].url = urls[i]; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[i].title.erase(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadTitle(&(entries_[i])); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Complete change, so tell the view to just rebuild itself. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnModelChanged(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Move a number of existing entries to a new position, reordering the table. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We determine the range of elements affected by the move, save the moved 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * elements, compact the remaining ones, and re-insert moved elements. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Expects |index_list| to be ordered ascending. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::MoveURLs(int insert_before, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int>& index_list) { 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (index_list.empty()) return; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(insert_before >= 0 && insert_before <= RowCount()); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The range of elements that needs to be reshuffled is [ |first|, |last| ). 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int first = std::min(insert_before, index_list.front()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last = std::max(insert_before, index_list.back() + 1); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the dragged elements. Also, adjust insertion point if it is before a 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dragged element. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Entry> moved_entries; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < index_list.size(); ++i) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) moved_entries.push_back(entries_[index_list[i]]); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index_list[i] == insert_before) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert_before++; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compact the range between beginning and insertion point, moving downwards. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t skip_count = 0; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = first; i < insert_before; ++i) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skip_count < index_list.size() && index_list[skip_count] == i) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_count++; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entries_[i - skip_count] = entries_[i]; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moving items down created a gap. We start compacting up after it. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first = insert_before; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert_before -= skip_count; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now compact up for elements after the insertion point. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_count = 0; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = last - 1; i >= first; --i) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skip_count < index_list.size() && 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index_list[index_list.size() - skip_count - 1] == i) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_count++; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[i + skip_count] = entries_[i]; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Insert moved elements. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(moved_entries.begin(), moved_entries.end(), 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.begin() + insert_before); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Possibly large change, so tell the view to just rebuild itself. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnModelChanged(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::Add(int index, const GURL& url) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index <= RowCount()); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.insert(entries_.begin() + static_cast<size_t>(index), Entry()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[index].url = url; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadTitle(&(entries_[index])); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnItemsAdded(index, 1); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::Remove(int index) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index < RowCount()); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry* entry = &(entries_[index]); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel any pending load requests now so we don't deref a bogus pointer when 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we get the loaded notification. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry->title_handle) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService* history_service = HistoryServiceFactory::GetForProfile( 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_, Profile::EXPLICIT_ACCESS); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_service->CancelRequest(entry->title_handle); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.erase(entries_.begin() + static_cast<size_t>(index)); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnItemsRemoved(index, 1); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::SetToCurrentlyOpenPages() { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the current entries. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (RowCount()) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Remove(0); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And add all tabs for all open browsers with our profile. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_index = 0; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = *it; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser->profile() != profile_) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Skip incognito browsers. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int tab_index = 0; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_index < browser->tab_strip_model()->count(); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++tab_index) { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL url = 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetWebContentsAt(tab_index)->GetURL(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldAddPage(url)) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Add(add_index++, url); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<GURL> CustomHomePagesTableModel::GetURLs() { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> urls(entries_.size()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < entries_.size(); ++i) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls[i] = entries_[i].url; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return urls; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CustomHomePagesTableModel::RowCount() { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(entries_.size()); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 207d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)base::string16 CustomHomePagesTableModel::GetText(int row, int column_id) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(column_id == 0); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(row >= 0 && row < RowCount()); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entries_[row].title.empty() ? FormattedURL(row) : entries_[row].title; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 213d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)base::string16 CustomHomePagesTableModel::GetTooltip(int row) { 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return entries_[row].title.empty() ? base::string16() : 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16(IDS_OPTIONS_STARTUP_PAGE_TOOLTIP, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[row].title, FormattedURL(row)); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::SetObserver(ui::TableModelObserver* observer) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_ = observer; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::LoadTitle(Entry* entry) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService* history_service = HistoryServiceFactory::GetForProfile( 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_, Profile::EXPLICIT_ACCESS); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_service) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->title_handle = history_service->QueryURL(entry->url, false, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &history_query_consumer_, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CustomHomePagesTableModel::OnGotTitle, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CustomHomePagesTableModel::OnGotTitle(HistoryService::Handle handle, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found_url, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const history::URLRow* row, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::VisitVector* visits) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int entry_index; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry* entry = 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetEntryByLoadHandle(&Entry::title_handle, handle, &entry_index); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The URLs changed before we were called back. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->title_handle = 0; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found_url && !row->title().empty()) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->title = row->title(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnItemsChanged(static_cast<int>(entry_index), 1); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CustomHomePagesTableModel::Entry* 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CustomHomePagesTableModel::GetEntryByLoadHandle( 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelableRequestProvider::Handle Entry::* member, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelableRequestProvider::Handle handle, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* index) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < entries_.size(); ++i) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entries_[i].*member == handle) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *index = static_cast<int>(i); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &entries_[i]; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 267d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)base::string16 CustomHomePagesTableModel::FormattedURL(int row) const { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string languages = 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 url = net::FormatUrl(entries_[row].url, languages); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = base::i18n::GetDisplayStringInLTRDirectionality(url); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 274