1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/toolbar/home_button.h" 6 7#include "base/prefs/pref_service.h" 8#include "chrome/browser/profiles/profile.h" 9#include "chrome/browser/ui/browser.h" 10#include "chrome/common/pref_names.h" 11#include "components/user_prefs/user_prefs.h" 12#include "grit/generated_resources.h" 13#include "ui/base/l10n/l10n_util.h" 14#include "ui/views/bubble/bubble_delegate.h" 15#include "ui/views/controls/label.h" 16#include "ui/views/controls/link.h" 17#include "ui/views/controls/link_listener.h" 18#include "ui/views/layout/grid_layout.h" 19#include "ui/views/layout/layout_constants.h" 20#include "ui/views/widget/widget.h" 21 22// HomePageUndoBubble -------------------------------------------------------- 23 24namespace { 25 26class HomePageUndoBubble : public views::BubbleDelegateView, 27 public views::LinkListener { 28 public: 29 static void ShowBubble(Browser* browser, 30 bool undo_value_is_ntp, 31 const GURL& undo_url, 32 views::View* anchor_view); 33 static void HideBubble(); 34 35 private: 36 HomePageUndoBubble(Browser* browser, bool undo_value_is_ntp, 37 const GURL& undo_url, views::View* anchor_view); 38 virtual ~HomePageUndoBubble(); 39 40 // views::BubbleDelegateView: 41 virtual void Init() OVERRIDE; 42 virtual void WindowClosing() OVERRIDE; 43 44 // views::LinkListener: 45 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; 46 47 static HomePageUndoBubble* home_page_undo_bubble_; 48 49 Browser* browser_; 50 bool undo_value_is_ntp_; 51 GURL undo_url_; 52 53 DISALLOW_COPY_AND_ASSIGN(HomePageUndoBubble); 54}; 55 56// static 57HomePageUndoBubble* HomePageUndoBubble::home_page_undo_bubble_ = NULL; 58 59void HomePageUndoBubble::ShowBubble(Browser* browser, 60 bool undo_value_is_ntp, 61 const GURL& undo_url, 62 views::View* anchor_view) { 63 HideBubble(); 64 home_page_undo_bubble_ = new HomePageUndoBubble(browser, 65 undo_value_is_ntp, 66 undo_url, 67 anchor_view); 68 views::BubbleDelegateView::CreateBubble(home_page_undo_bubble_); 69 home_page_undo_bubble_->StartFade(true); 70} 71 72void HomePageUndoBubble::HideBubble() { 73 if (home_page_undo_bubble_) 74 home_page_undo_bubble_->GetWidget()->Close(); 75} 76 77HomePageUndoBubble::HomePageUndoBubble( 78 Browser* browser, 79 bool undo_value_is_ntp, 80 const GURL& undo_url, 81 views::View* anchor_view) 82 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT), 83 browser_(browser), 84 undo_value_is_ntp_(undo_value_is_ntp), 85 undo_url_(undo_url) { 86} 87 88HomePageUndoBubble::~HomePageUndoBubble() { 89} 90 91void HomePageUndoBubble::Init() { 92 views::GridLayout* layout = new views::GridLayout(this); 93 SetLayoutManager(layout); 94 95 // Create two columns for the message and the undo link. 96 views::ColumnSet* cs = layout->AddColumnSet(0); 97 cs = layout->AddColumnSet(1); 98 cs->AddColumn(views::GridLayout::LEADING, views::GridLayout::BASELINE, 0, 99 views::GridLayout::USE_PREF, 0, 0); 100 cs->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 101 cs->AddColumn(views::GridLayout::CENTER, views::GridLayout::BASELINE, 0, 102 views::GridLayout::USE_PREF, 0, 0); 103 104 views::Label* message_label = new views::Label( 105 l10n_util::GetStringUTF16(IDS_TOOLBAR_INFORM_SET_HOME_PAGE)); 106 message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 107 layout->StartRow(0, 1); 108 layout->AddView(message_label); 109 110 views::Link* undo_link = new views::Link( 111 l10n_util::GetStringUTF16(IDS_ONE_CLICK_BUBBLE_UNDO)); 112 undo_link->set_listener(this); 113 layout->AddView(undo_link); 114} 115 116void HomePageUndoBubble::LinkClicked(views::Link* source, int event_flags) { 117 PrefService* prefs = user_prefs::UserPrefs::Get(browser_->profile()); 118 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, undo_value_is_ntp_); 119 prefs->SetString(prefs::kHomePage, undo_url_.spec()); 120 121 HideBubble(); 122} 123 124void HomePageUndoBubble::WindowClosing() { 125 // We have to reset |home_page_undo_bubble_| here, not in our destructor, 126 // because we'll be hidden first, then destroyed asynchronously. If we wait 127 // to reset this, and the user triggers a call to ShowBubble() while the 128 // window is hidden but not destroyed, GetWidget()->Close() would be 129 // called twice. 130 DCHECK_EQ(this, home_page_undo_bubble_); 131 home_page_undo_bubble_ = NULL; 132} 133 134} // namespace 135 136 137// HomeButton ----------------------------------------------------------- 138 139HomeButton::HomeButton( 140 views::ButtonListener* listener, 141 Browser* browser) 142 : ToolbarButton(listener, NULL), 143 browser_(browser) { 144} 145 146HomeButton::~HomeButton() { 147} 148 149bool HomeButton::GetDropFormats( 150 int* formats, 151 std::set<OSExchangeData::CustomFormat>* custom_formats) { 152 *formats = ui::OSExchangeData::URL; 153 return true; 154} 155 156bool HomeButton::CanDrop(const OSExchangeData& data) { 157 return data.HasURL(); 158} 159 160int HomeButton::OnDragUpdated(const ui::DropTargetEvent& event) { 161 return (event.source_operations() & ui::DragDropTypes::DRAG_LINK) ? 162 ui::DragDropTypes::DRAG_LINK : ui::DragDropTypes::DRAG_NONE; 163} 164 165int HomeButton::OnPerformDrop(const ui::DropTargetEvent& event) { 166 GURL new_homepage_url; 167 base::string16 title; 168 if (event.data().GetURLAndTitle( 169 ui::OSExchangeData::CONVERT_FILENAMES, &new_homepage_url, &title) && 170 new_homepage_url.is_valid()) { 171 PrefService* prefs = browser_->profile()->GetPrefs(); 172 bool old_is_ntp = prefs->GetBoolean(prefs::kHomePageIsNewTabPage); 173 GURL old_homepage(prefs->GetString(prefs::kHomePage)); 174 175 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false); 176 prefs->SetString(prefs::kHomePage, new_homepage_url.spec()); 177 178 HomePageUndoBubble::ShowBubble(browser_, old_is_ntp, old_homepage, this); 179 } 180 return ui::DragDropTypes::DRAG_NONE; 181} 182