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.
5 #include "chrome/browser/ui/views/toolbar/home_button.h"
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/views/settings_api_bubble_helper_views.h"
11 #include "chrome/common/pref_names.h"
12 #include "components/user_prefs/user_prefs.h"
13 #include "grit/generated_resources.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/views/bubble/bubble_delegate.h"
16 #include "ui/views/controls/label.h"
17 #include "ui/views/controls/link.h"
18 #include "ui/views/controls/link_listener.h"
19 #include "ui/views/layout/grid_layout.h"
20 #include "ui/views/layout/layout_constants.h"
21 #include "ui/views/widget/widget.h"
23 // HomePageUndoBubble --------------------------------------------------------
27 class HomePageUndoBubble
: public views::BubbleDelegateView
,
28 public views::LinkListener
{
30 static void ShowBubble(Browser
* browser
,
31 bool undo_value_is_ntp
,
33 views::View
* anchor_view
);
34 static void HideBubble();
37 HomePageUndoBubble(Browser
* browser
, bool undo_value_is_ntp
,
38 const GURL
& undo_url
, views::View
* anchor_view
);
39 virtual ~HomePageUndoBubble();
41 // views::BubbleDelegateView:
42 virtual void Init() OVERRIDE
;
43 virtual void WindowClosing() OVERRIDE
;
45 // views::LinkListener:
46 virtual void LinkClicked(views::Link
* source
, int event_flags
) OVERRIDE
;
48 static HomePageUndoBubble
* home_page_undo_bubble_
;
51 bool undo_value_is_ntp_
;
54 DISALLOW_COPY_AND_ASSIGN(HomePageUndoBubble
);
58 HomePageUndoBubble
* HomePageUndoBubble::home_page_undo_bubble_
= NULL
;
60 void HomePageUndoBubble::ShowBubble(Browser
* browser
,
61 bool undo_value_is_ntp
,
63 views::View
* anchor_view
) {
65 home_page_undo_bubble_
= new HomePageUndoBubble(browser
,
69 views::BubbleDelegateView::CreateBubble(home_page_undo_bubble_
)->Show();
72 void HomePageUndoBubble::HideBubble() {
73 if (home_page_undo_bubble_
)
74 home_page_undo_bubble_
->GetWidget()->Close();
77 HomePageUndoBubble::HomePageUndoBubble(
79 bool undo_value_is_ntp
,
81 views::View
* anchor_view
)
82 : BubbleDelegateView(anchor_view
, views::BubbleBorder::TOP_LEFT
),
84 undo_value_is_ntp_(undo_value_is_ntp
),
88 HomePageUndoBubble::~HomePageUndoBubble() {
91 void HomePageUndoBubble::Init() {
92 views::GridLayout
* layout
= new views::GridLayout(this);
93 SetLayoutManager(layout
);
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);
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
);
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
);
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());
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
130 DCHECK_EQ(this, home_page_undo_bubble_
);
131 home_page_undo_bubble_
= NULL
;
137 // HomeButton -----------------------------------------------------------
139 HomeButton::HomeButton(
140 views::ButtonListener
* listener
,
142 : ToolbarButton(listener
, NULL
),
146 HomeButton::~HomeButton() {
149 bool HomeButton::GetDropFormats(
151 std::set
<OSExchangeData::CustomFormat
>* custom_formats
) {
152 *formats
= ui::OSExchangeData::URL
;
156 bool HomeButton::CanDrop(const OSExchangeData
& data
) {
157 return data
.HasURL(ui::OSExchangeData::CONVERT_FILENAMES
);
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
;
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
));
175 prefs
->SetBoolean(prefs::kHomePageIsNewTabPage
, false);
176 prefs
->SetString(prefs::kHomePage
, new_homepage_url
.spec());
178 HomePageUndoBubble::ShowBubble(browser_
, old_is_ntp
, old_homepage
, this);
180 return ui::DragDropTypes::DRAG_NONE
;
183 void HomeButton::NotifyClick(const ui::Event
& event
) {
184 ToolbarButton::NotifyClick(event
);
185 extensions::MaybeShowExtensionControlledHomeNotification(browser_
);