Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / file_system / request_file_system_dialog_view.cc
blob69df25b19933d5350f7b8e6aff3a53ea4f5f96b3
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"
7 #include <cstdlib>
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"
21 namespace {
23 // Maximum width of the dialog in pixels.
24 const int kDialogMaxWidth = 320;
26 } // namespace
28 // static
29 void RequestFileSystemDialogView::ShowDialog(
30 content::WebContents* web_contents,
31 const extensions::Extension& extension,
32 base::WeakPtr<file_manager::Volume> volume,
33 bool writable,
34 const base::Callback<void(ui::DialogButton)>& callback) {
35 constrained_window::ShowWebModalDialogViews(
36 new RequestFileSystemDialogView(extension, volume, writable, callback),
37 web_contents);
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 {
54 switch (button) {
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);
61 default:
62 NOTREACHED();
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);
85 return true;
88 bool RequestFileSystemDialogView::Accept() {
89 callback_.Run(ui::DIALOG_BUTTON_OK);
90 return true;
93 RequestFileSystemDialogView::RequestFileSystemDialogView(
94 const extensions::Extension& extension,
95 base::WeakPtr<file_manager::Volume> volume,
96 bool writable,
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.
102 if (!volume.get()) {
103 base::ThreadTaskRunnerHandle::Get()->PostTask(
104 FROM_HERE, base::Bind(callback, ui::DIALOG_BUTTON_CANCEL));
105 return;
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()),
127 bold_style);
128 label->AddStyleRange(
129 gfx::Range(placeholder_offsets[1],
130 placeholder_offsets[1] + volume_name.length()),
131 bold_style);
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);