| 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 |