Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / infobars / confirm_infobar.cc
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/infobars/confirm_infobar_delegate.h"
9 #include "chrome/browser/ui/views/elevation_icon_setter.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
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
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
35 ConfirmInfoBar::~ConfirmInfoBar() {
36   // Ensure |elevation_icon_setter_| is destroyed before |ok_button_|.
37   elevation_icon_setter_.reset();
38 }
39
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
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
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
112 int ConfirmInfoBar::ContentMinimumWidth() {
113   return label_->GetMinimumSize().width() + link_->GetMinimumSize().width() +
114       NonLabelWidth();
115 }
116
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
125 ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
126   return delegate()->AsConfirmInfoBarDelegate();
127 }
128
129 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 }