Home | History | Annotate | Download | only in infobars
      1 // Copyright (c) 2012 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/infobars/before_translate_infobar.h"
      6 
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "chrome/browser/translate/translate_infobar_delegate.h"
      9 #include "grit/generated_resources.h"
     10 #include "ui/base/l10n/l10n_util.h"
     11 #include "ui/views/controls/button/label_button.h"
     12 #include "ui/views/controls/button/menu_button.h"
     13 #include "ui/views/controls/label.h"
     14 #include "ui/views/controls/menu/menu_item_view.h"
     15 
     16 BeforeTranslateInfoBar::BeforeTranslateInfoBar(
     17     InfoBarService* owner,
     18     TranslateInfoBarDelegate* delegate)
     19     : TranslateInfoBarBase(owner, delegate),
     20       label_1_(NULL),
     21       label_2_(NULL),
     22       language_menu_button_(NULL),
     23       accept_button_(NULL),
     24       deny_button_(NULL),
     25       never_translate_button_(NULL),
     26       always_translate_button_(NULL),
     27       options_menu_button_(NULL),
     28       options_menu_model_(delegate) {
     29 }
     30 
     31 BeforeTranslateInfoBar::~BeforeTranslateInfoBar() {
     32 }
     33 
     34 void BeforeTranslateInfoBar::Layout() {
     35   TranslateInfoBarBase::Layout();
     36 
     37   int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth());
     38   gfx::Size label_1_size = label_1_->GetPreferredSize();
     39   label_1_->SetBounds(StartX(), OffsetY(label_1_size),
     40       std::min(label_1_size.width(), available_width), label_1_size.height());
     41   available_width = std::max(0, available_width - label_1_size.width());
     42 
     43   gfx::Size language_button_size = language_menu_button_->GetPreferredSize();
     44   language_menu_button_->SetBounds(
     45       label_1_->bounds().right() + kButtonInLabelSpacing,
     46       OffsetY(language_button_size), language_button_size.width(),
     47       language_button_size.height());
     48 
     49   gfx::Size label_2_size = label_2_->GetPreferredSize();
     50   label_2_->SetBounds(
     51       language_menu_button_->bounds().right() + kButtonInLabelSpacing,
     52       OffsetY(label_2_size), std::min(label_2_size.width(), available_width),
     53       label_2_size.height());
     54 
     55   gfx::Size accept_button_size = accept_button_->GetPreferredSize();
     56   accept_button_->SetBounds(label_2_->bounds().right() + kEndOfLabelSpacing,
     57       OffsetY(accept_button_size), accept_button_size.width(),
     58       accept_button_size.height());
     59 
     60   gfx::Size deny_button_size = deny_button_->GetPreferredSize();
     61   deny_button_->SetBounds(
     62         accept_button_->bounds().right() + kButtonButtonSpacing,
     63         OffsetY(deny_button_size), deny_button_size.width(),
     64         deny_button_size.height());
     65 
     66   if (never_translate_button_) {
     67     gfx::Size never_button_size = never_translate_button_->GetPreferredSize();
     68     never_translate_button_->SetBounds(
     69           deny_button_->bounds().right() + kButtonButtonSpacing,
     70           OffsetY(never_button_size), never_button_size.width(),
     71           never_button_size.height());
     72   }
     73 
     74   if (always_translate_button_) {
     75     gfx::Size always_button_size = always_translate_button_->GetPreferredSize();
     76     always_translate_button_->SetBounds(
     77           deny_button_->bounds().right() + kButtonButtonSpacing,
     78           OffsetY(always_button_size), always_button_size.width(),
     79           always_button_size.height());
     80   }
     81 
     82   gfx::Size options_size = options_menu_button_->GetPreferredSize();
     83   options_menu_button_->SetBounds(EndX() - options_size.width(),
     84       OffsetY(options_size), options_size.width(), options_size.height());
     85 }
     86 
     87 void BeforeTranslateInfoBar::ViewHierarchyChanged(
     88     const ViewHierarchyChangedDetails& details) {
     89   if (!details.is_add || (details.child != this) || (label_1_ != NULL)) {
     90     TranslateInfoBarBase::ViewHierarchyChanged(details);
     91     return;
     92   }
     93 
     94   size_t offset = 0;
     95   string16 text(l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE,
     96                                            string16(), &offset));
     97 
     98   label_1_ = CreateLabel(text.substr(0, offset));
     99   AddChildView(label_1_);
    100 
    101   language_menu_button_ = CreateMenuButton(string16(), this);
    102   TranslateInfoBarDelegate* delegate = GetDelegate();
    103   language_menu_model_.reset(new TranslateLanguageMenuModel(
    104       TranslateLanguageMenuModel::ORIGINAL, delegate, this,
    105       language_menu_button_, false));
    106   AddChildView(language_menu_button_);
    107 
    108   label_2_ = CreateLabel(text.substr(offset));
    109   AddChildView(label_2_);
    110 
    111   accept_button_ = CreateLabelButton(this,
    112       l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_ACCEPT), false);
    113   AddChildView(accept_button_);
    114 
    115   deny_button_ = CreateLabelButton(this,
    116       l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_DENY), false);
    117   AddChildView(deny_button_);
    118 
    119   const string16& language(
    120       delegate->language_name_at(delegate->original_language_index()));
    121   if (delegate->ShouldShowNeverTranslateShortcut()) {
    122     DCHECK(!delegate->ShouldShowAlwaysTranslateShortcut());
    123     never_translate_button_ = CreateLabelButton(this,
    124         l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_NEVER_TRANSLATE,
    125                                    language), false);
    126     AddChildView(never_translate_button_);
    127   } else if (delegate->ShouldShowAlwaysTranslateShortcut()) {
    128     always_translate_button_ = CreateLabelButton(this,
    129         l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_ALWAYS_TRANSLATE,
    130                                    language), false);
    131     AddChildView(always_translate_button_);
    132   }
    133 
    134   options_menu_button_ = CreateMenuButton(
    135       l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), this);
    136   AddChildView(options_menu_button_);
    137 
    138   // This must happen after adding all other children so InfoBarView can ensure
    139   // the close button is the last child.
    140   TranslateInfoBarBase::ViewHierarchyChanged(details);
    141 
    142   // This must happen after adding all children because it triggers layout,
    143   // which assumes that particular children (e.g. the close button) have already
    144   // been added.
    145   UpdateLanguageButtonText(language_menu_button_,
    146       delegate->language_name_at(delegate->original_language_index()));
    147 }
    148 
    149 int BeforeTranslateInfoBar::ContentMinimumWidth() const {
    150   return
    151       (kButtonInLabelSpacing +
    152           language_menu_button_->GetPreferredSize().width() +
    153           kButtonInLabelSpacing) +
    154       (kEndOfLabelSpacing + accept_button_->GetPreferredSize().width()) +
    155       (kButtonButtonSpacing + deny_button_->GetPreferredSize().width()) +
    156       ((never_translate_button_ == NULL) ? 0 :
    157           (kButtonButtonSpacing +
    158               never_translate_button_->GetPreferredSize().width())) +
    159       ((always_translate_button_ == NULL) ? 0 :
    160           (kButtonButtonSpacing +
    161               always_translate_button_->GetPreferredSize().width())) +
    162       (kEndOfLabelSpacing + options_menu_button_->GetPreferredSize().width());
    163 }
    164 
    165 void BeforeTranslateInfoBar::ButtonPressed(views::Button* sender,
    166                                            const ui::Event& event) {
    167   if (!owner())
    168     return;  // We're closing; don't call anything, it might access the owner.
    169   TranslateInfoBarDelegate* delegate = GetDelegate();
    170   if (sender == accept_button_) {
    171     delegate->Translate();
    172   } else if (sender == deny_button_) {
    173     delegate->TranslationDeclined();
    174     RemoveSelf();
    175   } else if (sender == never_translate_button_) {
    176     delegate->NeverTranslatePageLanguage();
    177   } else if (sender == always_translate_button_) {
    178     delegate->AlwaysTranslatePageLanguage();
    179   } else {
    180     TranslateInfoBarBase::ButtonPressed(sender, event);
    181   }
    182 }
    183 
    184 void BeforeTranslateInfoBar::OnMenuButtonClicked(views::View* source,
    185                                                  const gfx::Point& point) {
    186   if (!owner())
    187     return;  // We're closing; don't call anything, it might access the owner.
    188   if (source == language_menu_button_) {
    189     RunMenuAt(language_menu_model_.get(), language_menu_button_,
    190               views::MenuItemView::TOPLEFT);
    191   } else {
    192     DCHECK_EQ(options_menu_button_, source);
    193     RunMenuAt(&options_menu_model_, options_menu_button_,
    194               views::MenuItemView::TOPRIGHT);
    195   }
    196 }
    197