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 24 namespace { 25 26 class 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 57 HomePageUndoBubble* HomePageUndoBubble::home_page_undo_bubble_ = NULL; 58 59 void 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 72 void HomePageUndoBubble::HideBubble() { 73 if (home_page_undo_bubble_) 74 home_page_undo_bubble_->GetWidget()->Close(); 75 } 76 77 HomePageUndoBubble::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 88 HomePageUndoBubble::~HomePageUndoBubble() { 89 } 90 91 void 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 116 void 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 124 void 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 139 HomeButton::HomeButton( 140 views::ButtonListener* listener, 141 Browser* browser) 142 : ToolbarButton(listener, NULL), 143 browser_(browser) { 144 } 145 146 HomeButton::~HomeButton() { 147 } 148 149 bool HomeButton::GetDropFormats( 150 int* formats, 151 std::set<OSExchangeData::CustomFormat>* custom_formats) { 152 *formats = ui::OSExchangeData::URL; 153 return true; 154 } 155 156 bool HomeButton::CanDrop(const OSExchangeData& data) { 157 return data.HasURL(); 158 } 159 160 int 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 165 int 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