• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
CreateInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate)19 scoped_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 
ConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate)27 ConfirmInfoBar::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 
~ConfirmInfoBar()35 ConfirmInfoBar::~ConfirmInfoBar() {
36   // Ensure |elevation_icon_setter_| is destroyed before |ok_button_|.
37   elevation_icon_setter_.reset();
38 }
39 
Layout()40 void 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 
ViewHierarchyChanged(const ViewHierarchyChangedDetails & details)64 void 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 
ButtonPressed(views::Button * sender,const ui::Event & event)96 void 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 
ContentMinimumWidth() const112 int ConfirmInfoBar::ContentMinimumWidth() const {
113   return label_->GetMinimumSize().width() + link_->GetMinimumSize().width() +
114       NonLabelWidth();
115 }
116 
LinkClicked(views::Link * source,int event_flags)117 void 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 
GetDelegate()125 ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
126   return delegate()->AsConfirmInfoBarDelegate();
127 }
128 
NonLabelWidth() const129 int 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