OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 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 "app/gfx/font.h" | |
6 #include "app/l10n_util.h" | |
7 #include "app/win_util.h" | |
8 #include "chrome/browser/browser_list.h" | |
9 #include "chrome/browser/browser_window.h" | |
10 #include "chrome/browser/chrome_thread.h" | |
11 #include "chrome/browser/extensions/extensions_ui.h" | |
12 #include "chrome/browser/extensions/pack_extension_job.h" | |
13 #include "chrome/browser/shell_dialogs.h" | |
14 #include "grit/generated_resources.h" | |
15 #include "views/controls/label.h" | |
16 #include "views/controls/button/native_button.h" | |
17 #include "views/controls/textfield/textfield.h" | |
18 #include "views/standard_layout.h" | |
19 #include "views/view.h" | |
20 #include "views/window/dialog_client_view.h" | |
21 #include "views/window/dialog_delegate.h" | |
22 #include "views/window/window.h" | |
23 | |
24 namespace { | |
25 | |
26 // Puts up the the pack dialog, which has this basic layout: | |
27 // | |
28 // Select the extension to pack. | |
29 // | |
30 // Extension root: [ ] [browse] | |
31 // Extension key file: [ ] [browse] | |
32 // | |
33 // [ok] [cancel] | |
34 class PackDialogContent | |
35 : public views::View, | |
36 public PackExtensionJob::Client, | |
37 public SelectFileDialog::Listener, | |
38 public views::ButtonListener, | |
39 public views::DialogDelegate { | |
40 public: | |
41 PackDialogContent() : ok_button_(NULL) { | |
42 using views::GridLayout; | |
43 | |
44 // Setup the layout. | |
45 views::GridLayout* layout = CreatePanelGridLayout(this); | |
46 SetLayoutManager(layout); | |
47 | |
48 views::ColumnSet* columns = layout->AddColumnSet(0); | |
49 columns->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, | |
50 GridLayout::USE_PREF, 0, 0); | |
51 columns->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); | |
52 columns->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, | |
53 GridLayout::USE_PREF, 0, 0); | |
54 columns->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); | |
55 columns->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, | |
56 GridLayout::USE_PREF, 0, 0); | |
57 | |
58 layout->StartRow(0, 0); | |
59 views::Label* heading = new views::Label( | |
60 l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_HEADING)); | |
61 heading->SetMultiLine(true); | |
62 heading->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
63 layout->AddView(heading, 5, 1, GridLayout::FILL, GridLayout::LEADING); | |
64 | |
65 layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); | |
66 | |
67 layout->StartRow(0, 0); | |
68 layout->AddView(new views::Label(l10n_util::GetString( | |
69 IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL))); | |
70 extension_root_textbox_ = new views::Textfield(); | |
71 extension_root_textbox_->set_default_width_in_chars(32); | |
72 layout->AddView(extension_root_textbox_); | |
73 extension_root_button_ = new views::NativeButton(this, l10n_util::GetString( | |
74 IDS_EXTENSION_PACK_DIALOG_BROWSE)); | |
75 layout->AddView(extension_root_button_); | |
76 | |
77 layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); | |
78 | |
79 layout->StartRow(0, 0); | |
80 layout->AddView(new views::Label(l10n_util::GetString( | |
81 IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL))); | |
82 private_key_textbox_ = new views::Textfield(); | |
83 private_key_textbox_->set_default_width_in_chars(32); | |
84 layout->AddView(private_key_textbox_); | |
85 private_key_button_ = new views::NativeButton(this, l10n_util::GetString( | |
86 IDS_EXTENSION_PACK_DIALOG_BROWSE)); | |
87 layout->AddView(private_key_button_); | |
88 } | |
89 | |
90 // PackExtensionJob::Client | |
91 virtual void OnPackSuccess(const FilePath& crx_file, | |
92 const FilePath& pem_file) { | |
93 ok_button_->SetEnabled(true); | |
94 std::wstring message; | |
95 if (!pem_file.empty()) { | |
96 message = l10n_util::GetStringF( | |
97 IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_NEW, | |
98 crx_file.ToWStringHack(), | |
99 pem_file.ToWStringHack()); | |
100 } else { | |
101 message = l10n_util::GetStringF( | |
102 IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_UPDATE, | |
103 crx_file.ToWStringHack()); | |
104 } | |
105 win_util::MessageBox(GetWindow()->GetNativeWindow(), message, | |
106 l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_SUCCESS_TITLE), | |
107 MB_OK | MB_SETFOREGROUND); | |
108 GetWindow()->Close(); | |
109 } | |
110 | |
111 void OnPackFailure(const std::wstring& error) { | |
112 ok_button_->SetEnabled(true); | |
113 win_util::MessageBox(GetWindow()->GetNativeWindow(), error, | |
114 l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_FAILURE_TITLE), | |
115 MB_OK | MB_SETFOREGROUND); | |
116 } | |
117 | |
118 private: | |
119 // DialogDelegate | |
120 virtual bool Accept() { | |
121 FilePath root_directory = FilePath::FromWStringHack( | |
122 extension_root_textbox_->text()); | |
123 FilePath key_file = FilePath::FromWStringHack(private_key_textbox_->text()); | |
124 | |
125 if (root_directory.empty()) { | |
126 if (extension_root_textbox_->text().empty()) { | |
127 OnPackFailure(l10n_util::GetString( | |
128 IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED)); | |
129 } else { | |
130 OnPackFailure(l10n_util::GetString( | |
131 IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID)); | |
132 } | |
133 | |
134 return false; | |
135 } | |
136 | |
137 if (!private_key_textbox_->text().empty() && key_file.empty()) { | |
138 OnPackFailure(l10n_util::GetString( | |
139 IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID)); | |
140 return false; | |
141 } | |
142 | |
143 pack_job_ = new PackExtensionJob(this, root_directory, key_file, | |
144 ChromeThread::GetMessageLoop(ChromeThread::FILE)); | |
145 | |
146 // Prevent the dialog from closing because PackExtensionJob is asynchronous. | |
147 // We need to wait to find out if it succeeded before closing the window. | |
148 // | |
149 // Also disable the OK button while this is going so the user understands | |
150 // that something is happening. | |
151 views::DialogClientView* dialog = static_cast<views::DialogClientView*>( | |
152 GetWindow()->GetClientView()); | |
153 ok_button_ = dialog->ok_button(); | |
154 ok_button_->SetEnabled(false); | |
155 return false; | |
156 } | |
157 | |
158 virtual void OnClose() { | |
159 if (pack_job_) | |
160 pack_job_->ClearClient(); | |
161 } | |
162 | |
163 // WindowDelegate | |
164 virtual std::wstring GetWindowTitle() const { | |
165 return l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_TITLE); | |
166 } | |
167 virtual views::View* GetContentsView() { | |
168 return this; | |
169 } | |
170 | |
171 // ButtonListener | |
172 virtual void ButtonPressed(views::Button* sender, const views::Event& event) { | |
173 file_dialog_ = SelectFileDialog::Create(this); | |
174 | |
175 if (sender == extension_root_button_) { | |
176 file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER, | |
177 l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_SELECT_ROOT), | |
178 FilePath::FromWStringHack(extension_root_textbox_->text()), | |
179 NULL, 0, FILE_PATH_LITERAL(""), | |
180 GetWindow()->GetNativeWindow(), | |
181 extension_root_textbox_); | |
182 } else { | |
183 static SelectFileDialog::FileTypeInfo info; | |
184 info.extensions.push_back(std::vector<FilePath::StringType>()); | |
185 info.extensions.front().push_back(FILE_PATH_LITERAL("pem")); | |
186 info.extension_description_overrides.push_back(l10n_util::GetString( | |
187 IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION)); | |
188 info.include_all_files = true; | |
189 | |
190 file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE, | |
191 l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_SELECT_KEY), | |
192 FilePath::FromWStringHack(private_key_textbox_->text()), | |
193 &info, 1, FILE_PATH_LITERAL(""), | |
194 GetWindow()->GetNativeWindow(), | |
195 private_key_textbox_); | |
196 } | |
197 } | |
198 | |
199 // SelectFileDialog::Listener | |
200 virtual void MultiFilesSelected( | |
201 const std::vector<FilePath>& files, void* params) {}; | |
202 virtual void FileSelectionCanceled(void* params) {}; | |
203 virtual void FileSelected(const FilePath& path, int index, void* params) { | |
204 static_cast<views::Textfield*>(params)->SetText(path.ToWStringHack()); | |
205 } | |
206 | |
207 views::Textfield* extension_root_textbox_; | |
208 views::Textfield* private_key_textbox_; | |
209 views::NativeButton* extension_root_button_; | |
210 views::NativeButton* private_key_button_; | |
211 views::NativeButton* ok_button_; | |
212 | |
213 scoped_refptr<SelectFileDialog> file_dialog_; | |
214 scoped_refptr<PackExtensionJob> pack_job_; | |
215 | |
216 DISALLOW_COPY_AND_ASSIGN(PackDialogContent); | |
217 }; | |
218 | |
219 } // namespace | |
220 | |
221 // static | |
222 void ExtensionsDOMHandler::ShowPackDialog() { | |
223 Browser* browser = BrowserList::GetLastActive(); | |
224 if (!browser) | |
225 return; | |
226 | |
227 BrowserWindow* window = browser->window(); | |
228 if (!window) | |
229 return; | |
230 | |
231 views::Window::CreateChromeWindow(window->GetNativeHandle(), | |
232 gfx::Rect(400, 0), new PackDialogContent())->Show(); | |
233 } | |
OLD | NEW |