Home | History | Annotate | Download | only in toolbar
      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/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"
     22 
     23 // HomePageUndoBubble --------------------------------------------------------
     24 
     25 namespace {
     26 
     27 class HomePageUndoBubble : public views::BubbleDelegateView,
     28                            public views::LinkListener {
     29  public:
     30   static void ShowBubble(Browser* browser,
     31                          bool undo_value_is_ntp,
     32                          const GURL& undo_url,
     33                          views::View* anchor_view);
     34   static void HideBubble();
     35 
     36  private:
     37   HomePageUndoBubble(Browser* browser, bool undo_value_is_ntp,
     38                      const GURL& undo_url, views::View* anchor_view);
     39   virtual ~HomePageUndoBubble();
     40 
     41   // views::BubbleDelegateView:
     42   virtual void Init() OVERRIDE;
     43   virtual void WindowClosing() OVERRIDE;
     44 
     45   // views::LinkListener:
     46   virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
     47 
     48   static HomePageUndoBubble* home_page_undo_bubble_;
     49 
     50   Browser* browser_;
     51   bool undo_value_is_ntp_;
     52   GURL undo_url_;
     53 
     54   DISALLOW_COPY_AND_ASSIGN(HomePageUndoBubble);
     55 };
     56 
     57 // static
     58 HomePageUndoBubble* HomePageUndoBubble::home_page_undo_bubble_ = NULL;
     59 
     60 void HomePageUndoBubble::ShowBubble(Browser* browser,
     61                                     bool undo_value_is_ntp,
     62                                     const GURL& undo_url,
     63                                     views::View* anchor_view) {
     64   HideBubble();
     65   home_page_undo_bubble_ = new HomePageUndoBubble(browser,
     66                                                   undo_value_is_ntp,
     67                                                   undo_url,
     68                                                   anchor_view);
     69   views::BubbleDelegateView::CreateBubble(home_page_undo_bubble_)->Show();
     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(ui::OSExchangeData::CONVERT_FILENAMES);
    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 
    183 void HomeButton::NotifyClick(const ui::Event& event) {
    184   ToolbarButton::NotifyClick(event);
    185   extensions::MaybeShowExtensionControlledHomeNotification(browser_);
    186 }
    187