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/extensions/api/file_system/request_file_system_dialog_view.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "chrome/grit/generated_resources.h"
12 #include "components/constrained_window/constrained_window_views.h"
13 #include "content/public/browser/web_contents.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/gfx/font.h"
16 #include "ui/gfx/range/range.h"
17 #include "ui/views/controls/styled_label.h"
18 #include "ui/views/layout/box_layout.h"
19 #include "ui/views/layout/layout_constants.h"
23 // Maximum width of the dialog in pixels.
24 const int kDialogMaxWidth
= 320;
29 void RequestFileSystemDialogView::ShowDialog(
30 content::WebContents
* web_contents
,
31 const extensions::Extension
& extension
,
32 base::WeakPtr
<file_manager::Volume
> volume
,
34 const base::Callback
<void(ui::DialogButton
)>& callback
) {
35 constrained_window::ShowWebModalDialogViews(
36 new RequestFileSystemDialogView(extension
, volume
, writable
, callback
),
40 RequestFileSystemDialogView::~RequestFileSystemDialogView() {
43 base::string16
RequestFileSystemDialogView::GetDialogTitle() const {
44 return l10n_util::GetStringUTF16(
45 IDS_FILE_SYSTEM_REQUEST_FILE_SYSTEM_DIALOG_TITLE
);
48 int RequestFileSystemDialogView::GetDefaultDialogButton() const {
49 return ui::DIALOG_BUTTON_CANCEL
;
52 base::string16
RequestFileSystemDialogView::GetDialogButtonLabel(
53 ui::DialogButton button
) const {
55 case ui::DIALOG_BUTTON_OK
:
56 return l10n_util::GetStringUTF16(
57 IDS_FILE_SYSTEM_REQUEST_FILE_SYSTEM_DIALOG_ALLOW_BUTTON
);
58 case ui::DIALOG_BUTTON_CANCEL
:
59 return l10n_util::GetStringUTF16(
60 IDS_FILE_SYSTEM_REQUEST_FILE_SYSTEM_DIALOG_DENY_BUTTON
);
64 return base::string16();
67 ui::ModalType
RequestFileSystemDialogView::GetModalType() const {
68 return ui::MODAL_TYPE_CHILD
;
71 views::View
* RequestFileSystemDialogView::GetContentsView() {
72 return contents_view_
;
75 views::Widget
* RequestFileSystemDialogView::GetWidget() {
76 return contents_view_
->GetWidget();
79 const views::Widget
* RequestFileSystemDialogView::GetWidget() const {
80 return contents_view_
->GetWidget();
83 bool RequestFileSystemDialogView::Cancel() {
84 callback_
.Run(ui::DIALOG_BUTTON_CANCEL
);
88 bool RequestFileSystemDialogView::Accept() {
89 callback_
.Run(ui::DIALOG_BUTTON_OK
);
93 RequestFileSystemDialogView::RequestFileSystemDialogView(
94 const extensions::Extension
& extension
,
95 base::WeakPtr
<file_manager::Volume
> volume
,
97 const base::Callback
<void(ui::DialogButton
)>& callback
)
98 : callback_(callback
), contents_view_(new views::View
) {
99 DCHECK(!callback_
.is_null());
101 // If the volume is gone, then cancel the dialog.
103 base::ThreadTaskRunnerHandle::Get()->PostTask(
104 FROM_HERE
, base::Bind(callback
, ui::DIALOG_BUTTON_CANCEL
));
108 const base::string16 app_name
= base::UTF8ToUTF16(extension
.name());
109 // TODO(mtomasz): Improve the dialog contents, so it's easier for the user
110 // to understand what device is being requested.
111 const base::string16 volume_name
=
112 base::UTF8ToUTF16(!volume
->volume_label().empty() ? volume
->volume_label()
113 : volume
->volume_id());
114 std::vector
<size_t> placeholder_offsets
;
115 const base::string16 message
= l10n_util::GetStringFUTF16(
116 writable
? IDS_FILE_SYSTEM_REQUEST_FILE_SYSTEM_DIALOG_WRITABLE_MESSAGE
117 : IDS_FILE_SYSTEM_REQUEST_FILE_SYSTEM_DIALOG_MESSAGE
,
118 app_name
, volume_name
, &placeholder_offsets
);
120 views::StyledLabel
* const label
= new views::StyledLabel(message
, nullptr);
121 views::StyledLabel::RangeStyleInfo bold_style
;
122 bold_style
.font_style
= gfx::Font::BOLD
;
124 DCHECK_EQ(2u, placeholder_offsets
.size());
125 label
->AddStyleRange(gfx::Range(placeholder_offsets
[0],
126 placeholder_offsets
[0] + app_name
.length()),
128 label
->AddStyleRange(
129 gfx::Range(placeholder_offsets
[1],
130 placeholder_offsets
[1] + volume_name
.length()),
133 views::BoxLayout
* const layout
= new views::BoxLayout(
134 views::BoxLayout::kHorizontal
, views::kButtonHEdgeMarginNew
,
135 views::kPanelVertMargin
, 0);
136 contents_view_
->SetLayoutManager(layout
);
138 label
->SizeToFit(kDialogMaxWidth
- 2 * views::kButtonHEdgeMarginNew
);
139 contents_view_
->AddChildView(label
);