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"
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/ui/views/elevation_icon_setter.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/infobars/core/confirm_infobar_delegate.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/window_open_disposition.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/button/label_button.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ConfirmInfoBarDelegate -----------------------------------------------------
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// static
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochscoped_ptr<infobars::InfoBar> ConfirmInfoBarDelegate::CreateInfoBar(
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<ConfirmInfoBarDelegate> delegate) {
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return scoped_ptr<infobars::InfoBar>(new ConfirmInfoBar(delegate.Pass()));
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ConfirmInfoBar -------------------------------------------------------------
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ConfirmInfoBar::ConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate)
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : InfoBarView(delegate.PassAs<infobars::InfoBarDelegate>()),
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      label_(NULL),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ok_button_(NULL),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cancel_button_(NULL),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      link_(NULL) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConfirmInfoBar::~ConfirmInfoBar() {
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Ensure |elevation_icon_setter_| is destroyed before |ok_button_|.
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  elevation_icon_setter_.reset();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfirmInfoBar::Layout() {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InfoBarView::Layout();
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int x = StartX();
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Labels labels;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  labels.push_back(label_);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  labels.push_back(link_);
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AssignWidths(&labels, std::max(0, EndX() - x - NonLabelWidth()));
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  label_->SetPosition(gfx::Point(x, OffsetY(label_)));
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!label_->text().empty())
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    x = label_->bounds().right() + kEndOfLabelSpacing;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ok_button_) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ok_button_->SetPosition(gfx::Point(x, OffsetY(ok_button_)));
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    x = ok_button_->bounds().right() + kButtonButtonSpacing;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (cancel_button_)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cancel_button_->SetPosition(gfx::Point(x, OffsetY(cancel_button_)));
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  link_->SetPosition(gfx::Point(EndX() - link_->width(), OffsetY(link_)));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ConfirmInfoBar::ViewHierarchyChanged(
65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const ViewHierarchyChangedDetails& details) {
66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (details.is_add && details.child == this && (label_ == NULL)) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConfirmInfoBarDelegate* delegate = GetDelegate();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    label_ = CreateLabel(delegate->GetMessageText());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(label_);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) {
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ok_button_ = CreateLabelButton(
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          this, delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK));
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      if (delegate->OKButtonTriggersUACPrompt())
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        elevation_icon_setter_.reset(new ElevationIconSetter(ok_button_));
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddChildView(ok_button_);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      cancel_button_ = CreateLabelButton(
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          this,
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddChildView(cancel_button_);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 link_text(delegate->GetLinkText());
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    link_ = CreateLink(link_text, this);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AddChildView(link_);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This must happen after adding all other children so InfoBarView can ensure
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the close button is the last child.
93a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  InfoBarView::ViewHierarchyChanged(details);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfirmInfoBar::ButtonPressed(views::Button* sender,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const ui::Event& event) {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!owner())
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // We're closing; don't call anything, it might access the owner.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfirmInfoBarDelegate* delegate = GetDelegate();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((ok_button_ != NULL) && sender == ok_button_) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->Accept())
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RemoveSelf();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if ((cancel_button_ != NULL) && (sender == cancel_button_)) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->Cancel())
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RemoveSelf();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InfoBarView::ButtonPressed(sender, event);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int ConfirmInfoBar::ContentMinimumWidth() const {
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return label_->GetMinimumSize().width() + link_->GetMinimumSize().width() +
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NonLabelWidth();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfirmInfoBar::LinkClicked(views::Link* source, int event_flags) {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!owner())
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // We're closing; don't call anything, it might access the owner.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(link_, source);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags)))
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveSelf();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return delegate()->AsConfirmInfoBarDelegate();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int ConfirmInfoBar::NonLabelWidth() const {
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int width = (label_->text().empty() || (!ok_button_ && !cancel_button_)) ?
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      0 : kEndOfLabelSpacing;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ok_button_)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    width += ok_button_->width() + (cancel_button_ ? kButtonButtonSpacing : 0);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  width += (cancel_button_ ? cancel_button_->width() : 0);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return width + ((link_->text().empty() || !width) ? 0 : kEndOfLabelSpacing);
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
137