15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/infobars/confirm_infobar.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/confirm_infobar_delegate.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/window_open_disposition.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/button/label_button.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ConfirmInfoBarDelegate -----------------------------------------------------
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InfoBar* ConfirmInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new ConfirmInfoBar(owner, this);
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ConfirmInfoBar -------------------------------------------------------------
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ConfirmInfoBar::ConfirmInfoBar(InfoBarService* owner,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ConfirmInfoBarDelegate* delegate)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : InfoBarView(owner, delegate),
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      label_(NULL),
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ok_button_(NULL),
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cancel_button_(NULL),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      link_(NULL) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConfirmInfoBar::~ConfirmInfoBar() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfirmInfoBar::Layout() {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InfoBarView::Layout();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth());
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size label_size = label_->GetPreferredSize();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_->SetBounds(StartX(), OffsetY(label_size),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::min(label_size.width(), available_width), label_size.height());
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  available_width = std::max(0, available_width - label_size.width());
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int button_x = label_->bounds().right() + kEndOfLabelSpacing;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ok_button_ != NULL) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size ok_size = ok_button_->GetPreferredSize();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ok_button_->SetBounds(button_x, OffsetY(ok_size), ok_size.width(),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ok_size.height());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button_x += ok_size.width() + kButtonButtonSpacing;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cancel_button_ != NULL) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size cancel_size = cancel_button_->GetPreferredSize();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cancel_button_->SetBounds(button_x, OffsetY(cancel_size),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              cancel_size.width(), cancel_size.height());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (link_ != NULL) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size link_size = link_->GetPreferredSize();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int link_width = std::min(link_size.width(), available_width);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link_->SetBounds(EndX() - link_width, OffsetY(link_size), link_width,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     link_size.height());
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ConfirmInfoBar::ViewHierarchyChanged(
68a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const ViewHierarchyChangedDetails& details) {
69a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (details.is_add && details.child == this && (label_ == NULL)) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConfirmInfoBarDelegate* delegate = GetDelegate();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    label_ = CreateLabel(delegate->GetMessageText());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(label_);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ok_button_ = CreateLabelButton(this,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_OK));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddChildView(ok_button_);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      cancel_button_ = CreateLabelButton(this,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_CANCEL));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddChildView(cancel_button_);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 link_text(delegate->GetLinkText());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!link_text.empty()) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      link_ = CreateLink(link_text, this);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddChildView(link_);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This must happen after adding all other children so InfoBarView can ensure
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the close button is the last child.
97a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  InfoBarView::ViewHierarchyChanged(details);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfirmInfoBar::ButtonPressed(views::Button* sender,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const ui::Event& event) {
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!owner())
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // We're closing; don't call anything, it might access the owner.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfirmInfoBarDelegate* delegate = GetDelegate();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((ok_button_ != NULL) && sender == ok_button_) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->Accept())
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RemoveSelf();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if ((cancel_button_ != NULL) && (sender == cancel_button_)) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->Cancel())
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RemoveSelf();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InfoBarView::ButtonPressed(sender, event);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ConfirmInfoBar::ContentMinimumWidth() const {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = (link_ == NULL) ? 0 : kEndOfLabelSpacing;  // Space before link
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int before_cancel_spacing = kEndOfLabelSpacing;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ok_button_ != NULL) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width += kEndOfLabelSpacing + ok_button_->GetPreferredSize().width();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    before_cancel_spacing = kButtonButtonSpacing;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return width + ((cancel_button_ == NULL) ? 0 :
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (before_cancel_spacing + cancel_button_->GetPreferredSize().width()));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfirmInfoBar::LinkClicked(views::Link* source, int event_flags) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!owner())
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // We're closing; don't call anything, it might access the owner.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(link_ != NULL);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(link_, source);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags)))
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveSelf();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return delegate()->AsConfirmInfoBarDelegate();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
139