1 // Copyright 2015 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.
5 #include "chrome/browser/ui/views/certificate_selector.h"
7 #include <stddef.h> // For size_t.
10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/certificate_viewer.h"
14 #include "chrome/grit/generated_resources.h"
15 #include "components/constrained_window/constrained_window_views.h"
16 #include "content/public/browser/web_contents.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/models/table_model.h"
19 #include "ui/base/models/table_model_observer.h"
20 #include "ui/views/controls/button/label_button.h"
21 #include "ui/views/controls/label.h"
22 #include "ui/views/controls/table/table_view.h"
23 #include "ui/views/layout/grid_layout.h"
24 #include "ui/views/layout/layout_constants.h"
25 #include "ui/views/widget/widget.h"
26 #include "ui/views/window/dialog_client_view.h"
30 class CertificateSelector::CertificateTableModel
: public ui::TableModel
{
32 explicit CertificateTableModel(const net::CertificateList
& certificates
);
35 int RowCount() override
;
36 base::string16
GetText(int index
, int column_id
) override
;
37 void SetObserver(ui::TableModelObserver
* observer
) override
;
40 std::vector
<base::string16
> items_
;
42 DISALLOW_COPY_AND_ASSIGN(CertificateTableModel
);
45 CertificateSelector::CertificateTableModel::CertificateTableModel(
46 const net::CertificateList
& certificates
) {
47 for (const scoped_refptr
<net::X509Certificate
>& cert
: certificates
) {
48 items_
.push_back(l10n_util::GetStringFUTF16(
49 IDS_CERT_SELECTOR_TABLE_CERT_FORMAT
,
50 base::UTF8ToUTF16(cert
->subject().GetDisplayName()),
51 base::UTF8ToUTF16(cert
->issuer().GetDisplayName())));
55 int CertificateSelector::CertificateTableModel::RowCount() {
59 base::string16
CertificateSelector::CertificateTableModel::GetText(
62 DCHECK_EQ(column_id
, 0);
64 DCHECK_LT(static_cast<size_t>(index
), items_
.size());
69 void CertificateSelector::CertificateTableModel::SetObserver(
70 ui::TableModelObserver
* observer
) {
73 CertificateSelector::CertificateSelector(
74 const net::CertificateList
& certificates
,
75 content::WebContents
* web_contents
)
76 : certificates_(certificates
),
77 model_(new CertificateTableModel(certificates
)),
78 web_contents_(web_contents
),
80 view_cert_button_(nullptr) {
84 CertificateSelector::~CertificateSelector() {
85 table_
->SetModel(nullptr);
88 void CertificateSelector::Show() {
89 constrained_window::ShowWebModalDialogViews(this, web_contents_
);
91 // Select the first row automatically. This must be done after the dialog has
96 void CertificateSelector::InitWithText(const base::string16
& text
) {
97 views::GridLayout
* const layout
= views::GridLayout::CreatePanel(this);
98 SetLayoutManager(layout
);
100 // The dimensions of the certificate selector table view, in pixels.
101 const int kTableViewWidth
= 400;
102 const int kTableViewHeight
= 100;
104 const int kColumnSetId
= 0;
105 views::ColumnSet
* const column_set
= layout
->AddColumnSet(kColumnSetId
);
106 column_set
->AddColumn(views::GridLayout::FILL
, views::GridLayout::FILL
, 1,
107 views::GridLayout::USE_PREF
, 0, 0);
109 layout
->StartRow(0, kColumnSetId
);
110 scoped_ptr
<views::Label
> label(new views::Label(text
));
111 label
->SetMultiLine(true);
112 label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
113 label
->SetAllowCharacterBreak(true);
114 label
->SizeToFit(kTableViewWidth
);
115 layout
->AddView(label
.release());
117 layout
->AddPaddingRow(0, views::kRelatedControlVerticalSpacing
);
119 std::vector
<ui::TableColumn
> columns
;
120 columns
.push_back(ui::TableColumn());
121 table_
= new views::TableView(model_
.get(), columns
, views::TEXT_ONLY
,
122 true /* single_selection */);
123 table_
->SetObserver(this);
124 layout
->StartRow(1, kColumnSetId
);
125 layout
->AddView(table_
->CreateParentIfNecessary(), 1, 1,
126 views::GridLayout::FILL
, views::GridLayout::FILL
,
127 kTableViewWidth
, kTableViewHeight
);
129 layout
->AddPaddingRow(0, views::kRelatedControlVerticalSpacing
);
132 net::X509Certificate
* CertificateSelector::GetSelectedCert() const {
133 const int selected
= table_
->FirstSelectedRow();
134 if (selected
< 0) // Nothing is selected in |table_|.
136 CHECK_LT(static_cast<size_t>(selected
), certificates_
.size());
137 return certificates_
[selected
].get();
140 bool CertificateSelector::CanResize() const {
144 base::string16
CertificateSelector::GetWindowTitle() const {
145 return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE
);
148 bool CertificateSelector::IsDialogButtonEnabled(ui::DialogButton button
) const {
149 return button
!= ui::DIALOG_BUTTON_OK
|| GetSelectedCert() != nullptr;
152 views::View
* CertificateSelector::GetInitiallyFocusedView() {
157 views::View
* CertificateSelector::CreateExtraView() {
158 DCHECK(!view_cert_button_
);
159 scoped_ptr
<views::LabelButton
> button(new views::LabelButton(
160 this, l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON
)));
161 button
->SetStyle(views::Button::STYLE_BUTTON
);
162 view_cert_button_
= button
.get();
163 return button
.release();
166 ui::ModalType
CertificateSelector::GetModalType() const {
167 return ui::MODAL_TYPE_CHILD
;
170 void CertificateSelector::ButtonPressed(views::Button
* sender
,
171 const ui::Event
& event
) {
172 if (sender
== view_cert_button_
) {
173 net::X509Certificate
* const cert
= GetSelectedCert();
175 ShowCertificateViewer(web_contents_
,
176 web_contents_
->GetTopLevelNativeWindow(), cert
);
180 void CertificateSelector::OnSelectionChanged() {
181 GetDialogClientView()->ok_button()->SetEnabled(GetSelectedCert() != nullptr);
184 void CertificateSelector::OnDoubleClick() {
186 GetWidget()->Close();
189 } // namespace chrome