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/confirm_infobar.h" 6 7#include "base/logging.h" 8#include "chrome/browser/ui/views/elevation_icon_setter.h" 9#include "components/infobars/core/confirm_infobar_delegate.h" 10#include "ui/base/window_open_disposition.h" 11#include "ui/views/controls/button/label_button.h" 12#include "ui/views/controls/label.h" 13#include "ui/views/controls/link.h" 14 15 16// ConfirmInfoBarDelegate ----------------------------------------------------- 17 18// static 19scoped_ptr<infobars::InfoBar> ConfirmInfoBarDelegate::CreateInfoBar( 20 scoped_ptr<ConfirmInfoBarDelegate> delegate) { 21 return scoped_ptr<infobars::InfoBar>(new ConfirmInfoBar(delegate.Pass())); 22} 23 24 25// ConfirmInfoBar ------------------------------------------------------------- 26 27ConfirmInfoBar::ConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate) 28 : InfoBarView(delegate.PassAs<infobars::InfoBarDelegate>()), 29 label_(NULL), 30 ok_button_(NULL), 31 cancel_button_(NULL), 32 link_(NULL) { 33} 34 35ConfirmInfoBar::~ConfirmInfoBar() { 36 // Ensure |elevation_icon_setter_| is destroyed before |ok_button_|. 37 elevation_icon_setter_.reset(); 38} 39 40void ConfirmInfoBar::Layout() { 41 InfoBarView::Layout(); 42 43 int x = StartX(); 44 Labels labels; 45 labels.push_back(label_); 46 labels.push_back(link_); 47 AssignWidths(&labels, std::max(0, EndX() - x - NonLabelWidth())); 48 49 label_->SetPosition(gfx::Point(x, OffsetY(label_))); 50 if (!label_->text().empty()) 51 x = label_->bounds().right() + kEndOfLabelSpacing; 52 53 if (ok_button_) { 54 ok_button_->SetPosition(gfx::Point(x, OffsetY(ok_button_))); 55 x = ok_button_->bounds().right() + kButtonButtonSpacing; 56 } 57 58 if (cancel_button_) 59 cancel_button_->SetPosition(gfx::Point(x, OffsetY(cancel_button_))); 60 61 link_->SetPosition(gfx::Point(EndX() - link_->width(), OffsetY(link_))); 62} 63 64void ConfirmInfoBar::ViewHierarchyChanged( 65 const ViewHierarchyChangedDetails& details) { 66 if (details.is_add && details.child == this && (label_ == NULL)) { 67 ConfirmInfoBarDelegate* delegate = GetDelegate(); 68 label_ = CreateLabel(delegate->GetMessageText()); 69 AddChildView(label_); 70 71 if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) { 72 ok_button_ = CreateLabelButton( 73 this, delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)); 74 if (delegate->OKButtonTriggersUACPrompt()) 75 elevation_icon_setter_.reset(new ElevationIconSetter(ok_button_)); 76 AddChildView(ok_button_); 77 } 78 79 if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) { 80 cancel_button_ = CreateLabelButton( 81 this, 82 delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL)); 83 AddChildView(cancel_button_); 84 } 85 86 base::string16 link_text(delegate->GetLinkText()); 87 link_ = CreateLink(link_text, this); 88 AddChildView(link_); 89 } 90 91 // This must happen after adding all other children so InfoBarView can ensure 92 // the close button is the last child. 93 InfoBarView::ViewHierarchyChanged(details); 94} 95 96void ConfirmInfoBar::ButtonPressed(views::Button* sender, 97 const ui::Event& event) { 98 if (!owner()) 99 return; // We're closing; don't call anything, it might access the owner. 100 ConfirmInfoBarDelegate* delegate = GetDelegate(); 101 if ((ok_button_ != NULL) && sender == ok_button_) { 102 if (delegate->Accept()) 103 RemoveSelf(); 104 } else if ((cancel_button_ != NULL) && (sender == cancel_button_)) { 105 if (delegate->Cancel()) 106 RemoveSelf(); 107 } else { 108 InfoBarView::ButtonPressed(sender, event); 109 } 110} 111 112int ConfirmInfoBar::ContentMinimumWidth() const { 113 return label_->GetMinimumSize().width() + link_->GetMinimumSize().width() + 114 NonLabelWidth(); 115} 116 117void ConfirmInfoBar::LinkClicked(views::Link* source, int event_flags) { 118 if (!owner()) 119 return; // We're closing; don't call anything, it might access the owner. 120 DCHECK_EQ(link_, source); 121 if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags))) 122 RemoveSelf(); 123} 124 125ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() { 126 return delegate()->AsConfirmInfoBarDelegate(); 127} 128 129int ConfirmInfoBar::NonLabelWidth() const { 130 int width = (label_->text().empty() || (!ok_button_ && !cancel_button_)) ? 131 0 : kEndOfLabelSpacing; 132 if (ok_button_) 133 width += ok_button_->width() + (cancel_button_ ? kButtonButtonSpacing : 0); 134 width += (cancel_button_ ? cancel_button_->width() : 0); 135 return width + ((link_->text().empty() || !width) ? 0 : kEndOfLabelSpacing); 136} 137