| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 "chrome/browser/chromeos/options/language_config_view.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "app/l10n_util.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "chrome/browser/browser_process.h" | |
| 12 #include "chrome/browser/chromeos/input_method/input_method_util.h" | |
| 13 #include "chrome/browser/chromeos/options/language_chewing_config_view.h" | |
| 14 #include "chrome/browser/chromeos/options/language_hangul_config_view.h" | |
| 15 #include "chrome/browser/chromeos/options/language_mozc_config_view.h" | |
| 16 #include "chrome/browser/chromeos/options/language_pinyin_config_view.h" | |
| 17 #include "chrome/browser/chromeos/options/options_window_view.h" | |
| 18 #include "chrome/browser/chromeos/preferences.h" | |
| 19 #include "chrome/browser/metrics/user_metrics.h" | |
| 20 #include "chrome/browser/prefs/pref_service.h" | |
| 21 #include "chrome/browser/profiles/profile.h" | |
| 22 #include "chrome/browser/ui/views/restart_message_box.h" | |
| 23 #include "chrome/browser/ui/views/window.h" | |
| 24 #include "chrome/common/notification_type.h" | |
| 25 #include "chrome/common/pref_names.h" | |
| 26 #include "gfx/font.h" | |
| 27 #include "grit/chromium_strings.h" | |
| 28 #include "grit/generated_resources.h" | |
| 29 #include "grit/locale_settings.h" | |
| 30 #include "views/controls/button/checkbox.h" | |
| 31 #include "views/controls/label.h" | |
| 32 #include "views/fill_layout.h" | |
| 33 #include "views/standard_layout.h" | |
| 34 #include "views/window/window.h" | |
| 35 | |
| 36 namespace chromeos { | |
| 37 using views::ColumnSet; | |
| 38 using views::GridLayout; | |
| 39 | |
| 40 namespace { | |
| 41 | |
| 42 // The width of the preferred language table shown on the left side. | |
| 43 const int kPreferredLanguageTableWidth = 300; | |
| 44 | |
| 45 // Creates the LanguageHangulConfigView. The function is used to create | |
| 46 // the object via a function pointer. See also InitInputMethodConfigViewMap(). | |
| 47 views::DialogDelegate* CreateLanguageChewingConfigView(Profile* profile) { | |
| 48 return new LanguageChewingConfigView(profile); | |
| 49 } | |
| 50 views::DialogDelegate* CreateLanguageHangulConfigView(Profile* profile) { | |
| 51 return new LanguageHangulConfigView(profile); | |
| 52 } | |
| 53 views::DialogDelegate* CreateLanguagePinyinConfigView(Profile* profile) { | |
| 54 return new LanguagePinyinConfigView(profile); | |
| 55 } | |
| 56 views::DialogDelegate* CreateLanguageMozcConfigView(Profile* profile) { | |
| 57 return new LanguageMozcConfigView(profile); | |
| 58 } | |
| 59 | |
| 60 // The tags are used to identify buttons in ButtonPressed(). | |
| 61 enum ButtonTag { | |
| 62 kChangeUiLanguageButton, | |
| 63 kConfigureInputMethodButton, | |
| 64 kRemoveLanguageButton, | |
| 65 kSelectInputMethodButton, | |
| 66 }; | |
| 67 | |
| 68 // The column set IDs are used for creating the per-language config view. | |
| 69 const int kPerLanguageTitleColumnSetId = 1; | |
| 70 const int kPerLanguageDoubleColumnSetId = 2; | |
| 71 const int kPerLanguageSingleColumnSetId = 3; | |
| 72 | |
| 73 } // namespace | |
| 74 | |
| 75 // This is a native button associated with input method information. | |
| 76 class InputMethodButton : public views::NativeButton { | |
| 77 public: | |
| 78 InputMethodButton(views::ButtonListener* listener, | |
| 79 const std::wstring& label, | |
| 80 const std::string& input_method_id) | |
| 81 : views::NativeButton(listener, label), | |
| 82 input_method_id_(input_method_id) { | |
| 83 } | |
| 84 | |
| 85 const std::string& input_method_id() const { | |
| 86 return input_method_id_; | |
| 87 } | |
| 88 | |
| 89 private: | |
| 90 std::string input_method_id_; | |
| 91 DISALLOW_COPY_AND_ASSIGN(InputMethodButton); | |
| 92 }; | |
| 93 | |
| 94 // This is a native button associated with UI language information. | |
| 95 class UiLanguageButton : public views::NativeButton { | |
| 96 public: | |
| 97 UiLanguageButton(views::ButtonListener* listener, | |
| 98 const std::wstring& label, | |
| 99 const std::string& language_code) | |
| 100 : views::NativeButton(listener, label), | |
| 101 language_code_(language_code) { | |
| 102 } | |
| 103 | |
| 104 const std::string& language_code() const { | |
| 105 return language_code_; | |
| 106 } | |
| 107 | |
| 108 private: | |
| 109 std::string language_code_; | |
| 110 DISALLOW_COPY_AND_ASSIGN(UiLanguageButton); | |
| 111 }; | |
| 112 | |
| 113 // This is a checkbox button associated with input method information. | |
| 114 class InputMethodCheckbox : public views::Checkbox { | |
| 115 public: | |
| 116 InputMethodCheckbox(const std::wstring& display_name, | |
| 117 const std::string& input_method_id) | |
| 118 : views::Checkbox(display_name), | |
| 119 input_method_id_(input_method_id) { | |
| 120 } | |
| 121 | |
| 122 const std::string& input_method_id() const { | |
| 123 return input_method_id_; | |
| 124 } | |
| 125 | |
| 126 private: | |
| 127 std::string input_method_id_; | |
| 128 DISALLOW_COPY_AND_ASSIGN(InputMethodCheckbox); | |
| 129 }; | |
| 130 | |
| 131 LanguageConfigView::LanguageConfigView(Profile* profile) | |
| 132 : OptionsPageView(profile), | |
| 133 model_(profile->GetPrefs()), | |
| 134 root_container_(NULL), | |
| 135 right_container_(NULL), | |
| 136 remove_language_button_(NULL), | |
| 137 preferred_language_table_(NULL) { | |
| 138 } | |
| 139 | |
| 140 LanguageConfigView::~LanguageConfigView() { | |
| 141 } | |
| 142 | |
| 143 void LanguageConfigView::ButtonPressed( | |
| 144 views::Button* sender, const views::Event& event) { | |
| 145 if (sender->tag() == kRemoveLanguageButton) { | |
| 146 OnRemoveLanguage(); | |
| 147 } else if (sender->tag() == kSelectInputMethodButton) { | |
| 148 InputMethodCheckbox* checkbox = | |
| 149 static_cast<InputMethodCheckbox*>(sender); | |
| 150 const std::string& input_method_id = checkbox->input_method_id(); | |
| 151 model_.SetInputMethodActivated(input_method_id, checkbox->checked()); | |
| 152 if (checkbox->checked()) { | |
| 153 EnableAllCheckboxes(); | |
| 154 } else { | |
| 155 MaybeDisableLastCheckbox(); | |
| 156 } | |
| 157 } else if (sender->tag() == kConfigureInputMethodButton) { | |
| 158 InputMethodButton* button = static_cast<InputMethodButton*>(sender); | |
| 159 views::DialogDelegate* config_view = | |
| 160 CreateInputMethodConfigureView(button->input_method_id()); | |
| 161 if (!config_view) { | |
| 162 DLOG(FATAL) << "Config view not found: " << button->input_method_id(); | |
| 163 return; | |
| 164 } | |
| 165 views::Window* window = browser::CreateViewsWindow( | |
| 166 GetOptionsViewParent(), gfx::Rect(), config_view); | |
| 167 window->SetIsAlwaysOnTop(true); | |
| 168 window->Show(); | |
| 169 } else if (sender->tag() == kChangeUiLanguageButton) { | |
| 170 UiLanguageButton* button = static_cast<UiLanguageButton*>(sender); | |
| 171 PrefService* prefs = g_browser_process->local_state(); | |
| 172 if (prefs) { | |
| 173 prefs->SetString(prefs::kApplicationLocale, button->language_code()); | |
| 174 prefs->SavePersistentPrefs(); | |
| 175 RestartMessageBox::ShowMessageBox(GetWindow()->GetNativeWindow()); | |
| 176 } | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 std::wstring LanguageConfigView::GetDialogButtonLabel( | |
| 181 MessageBoxFlags::DialogButton button) const { | |
| 182 if (button == MessageBoxFlags::DIALOGBUTTON_OK) { | |
| 183 return UTF16ToWide(l10n_util::GetStringUTF16(IDS_DONE)); | |
| 184 } | |
| 185 return L""; | |
| 186 } | |
| 187 | |
| 188 std::wstring LanguageConfigView::GetWindowTitle() const { | |
| 189 return UTF16ToWide(l10n_util::GetStringUTF16( | |
| 190 IDS_OPTIONS_SETTINGS_LANGUAGES_DIALOG_TITLE)); | |
| 191 } | |
| 192 | |
| 193 void LanguageConfigView::Layout() { | |
| 194 // Not sure why but this is needed to show contents in the dialog. | |
| 195 root_container_->SetBounds(0, 0, width(), height()); | |
| 196 } | |
| 197 | |
| 198 gfx::Size LanguageConfigView::GetPreferredSize() { | |
| 199 return gfx::Size(views::Window::GetLocalizedContentsSize( | |
| 200 IDS_LANGUAGES_INPUT_DIALOG_WIDTH_CHARS, | |
| 201 IDS_LANGUAGES_INPUT_DIALOG_HEIGHT_LINES)); | |
| 202 } | |
| 203 | |
| 204 void LanguageConfigView::OnSelectionChanged() { | |
| 205 right_container_->RemoveAllChildViews(true); // Delete the child views. | |
| 206 | |
| 207 const int row = preferred_language_table_->GetFirstSelectedRow(); | |
| 208 const std::string& language_code = model_.preferred_language_code_at(row); | |
| 209 | |
| 210 // Count the number of all active input methods. | |
| 211 std::vector<std::string> active_input_method_ids; | |
| 212 model_.GetActiveInputMethodIds(&active_input_method_ids); | |
| 213 const int num_all_active_input_methods = active_input_method_ids.size(); | |
| 214 | |
| 215 // Count the number of active input methods for the selected language. | |
| 216 int num_selected_active_input_methods = | |
| 217 model_.CountNumActiveInputMethods(language_code); | |
| 218 | |
| 219 bool remove_button_enabled = false; | |
| 220 // Allow removing the language only if the following conditions are met: | |
| 221 // 1. There are more than one language. | |
| 222 // 2. The languge in the current row is not set to the display language. | |
| 223 // 3. Removing the selected language does not result in "zero input method". | |
| 224 if (preferred_language_table_->GetRowCount() > 1 && | |
| 225 language_code != g_browser_process->GetApplicationLocale() && | |
| 226 num_all_active_input_methods > num_selected_active_input_methods) { | |
| 227 remove_button_enabled = true; | |
| 228 } | |
| 229 remove_language_button_->SetEnabled(remove_button_enabled); | |
| 230 | |
| 231 // Add the per language config view to the right area. | |
| 232 right_container_->AddChildView(CreatePerLanguageConfigView(language_code)); | |
| 233 MaybeDisableLastCheckbox(); | |
| 234 // Layout the right container. This is needed for the contents on the | |
| 235 // right to be displayed properly. | |
| 236 right_container_->Layout(); | |
| 237 } | |
| 238 | |
| 239 string16 LanguageConfigView::GetText(int row, int column_id) { | |
| 240 if (row >= 0 && row < static_cast<int>( | |
| 241 model_.num_preferred_language_codes())) { | |
| 242 return input_method::GetLanguageDisplayNameFromCode( | |
| 243 model_.preferred_language_code_at(row)); | |
| 244 } | |
| 245 NOTREACHED(); | |
| 246 return string16(); | |
| 247 } | |
| 248 | |
| 249 void LanguageConfigView::SetObserver(ui::TableModelObserver* observer) { | |
| 250 // We don't need the observer for the table mode, since we implement the | |
| 251 // table model as part of the LanguageConfigView class. | |
| 252 // http://crbug.com/38266 | |
| 253 } | |
| 254 | |
| 255 int LanguageConfigView::RowCount() { | |
| 256 // Returns the number of rows of the language table. | |
| 257 return model_.num_preferred_language_codes(); | |
| 258 } | |
| 259 | |
| 260 void LanguageConfigView::ItemChanged(views::Combobox* combobox, | |
| 261 int prev_index, | |
| 262 int new_index) { | |
| 263 // Ignore the first item used for showing "Add language". | |
| 264 if (new_index <= 0) { | |
| 265 return; | |
| 266 } | |
| 267 // Get the language selected. | |
| 268 std::string language_selected = add_language_combobox_model_-> | |
| 269 GetLocaleFromIndex( | |
| 270 add_language_combobox_model_->GetLanguageIndex(new_index)); | |
| 271 OnAddLanguage(language_selected); | |
| 272 } | |
| 273 | |
| 274 void LanguageConfigView::InitControlLayout() { | |
| 275 // Initialize the map. | |
| 276 InitInputMethodConfigViewMap(); | |
| 277 | |
| 278 root_container_ = new views::View; | |
| 279 AddChildView(root_container_); | |
| 280 | |
| 281 // Set up the layout manager for the root container. We'll place the | |
| 282 // language table on the left, and the per language config on the right. | |
| 283 GridLayout* root_layout = new GridLayout(root_container_); | |
| 284 root_container_->SetLayoutManager(root_layout); | |
| 285 root_layout->SetInsets(kPanelVertMargin, kPanelHorizMargin, | |
| 286 kPanelVertMargin, kPanelHorizMargin); | |
| 287 | |
| 288 // Set up column sets for the grid layout. | |
| 289 const int kMainColumnSetId = 0; | |
| 290 ColumnSet* column_set = root_layout->AddColumnSet(kMainColumnSetId); | |
| 291 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, | |
| 292 GridLayout::FIXED, kPreferredLanguageTableWidth, 0); | |
| 293 column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); | |
| 294 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1.0, | |
| 295 GridLayout::USE_PREF, 0, 0); | |
| 296 const int kBottomColumnSetId = 1; | |
| 297 column_set = root_layout->AddColumnSet(kBottomColumnSetId); | |
| 298 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
| 299 GridLayout::USE_PREF, 0, 0); | |
| 300 | |
| 301 // Set up the container for the contents on the right. Just adds a | |
| 302 // place holder here. This will get replaced in OnSelectionChanged(). | |
| 303 right_container_ = new views::View; | |
| 304 right_container_->SetLayoutManager(new views::FillLayout); | |
| 305 right_container_->AddChildView(new views::View); | |
| 306 | |
| 307 // Add the contents on the left and the right. | |
| 308 root_layout->StartRow(1 /* expand */, kMainColumnSetId); | |
| 309 root_layout->AddView(CreateContentsOnLeft()); | |
| 310 root_layout->AddView(right_container_); | |
| 311 | |
| 312 // Add the contents on the bottom. | |
| 313 root_layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); | |
| 314 root_layout->StartRow(0, kBottomColumnSetId); | |
| 315 root_layout->AddView(CreateContentsOnBottom()); | |
| 316 | |
| 317 // Select the first row in the language table. | |
| 318 // There should be at least one language in the table, but we check it | |
| 319 // here so this won't result in crash in case there is no row in the table. | |
| 320 if (model_.num_preferred_language_codes() > 0) { | |
| 321 preferred_language_table_->SelectRow(0); | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 void LanguageConfigView::Show(Profile* profile, gfx::NativeWindow parent) { | |
| 326 UserMetrics::RecordAction(UserMetricsAction("LanguageConfigView_Open")); | |
| 327 views::Window* window = browser::CreateViewsWindow( | |
| 328 parent, gfx::Rect(), new LanguageConfigView(profile)); | |
| 329 window->SetIsAlwaysOnTop(true); | |
| 330 window->Show(); | |
| 331 } | |
| 332 | |
| 333 void LanguageConfigView::InitInputMethodConfigViewMap() { | |
| 334 input_method_config_view_map_["chewing"] = CreateLanguageChewingConfigView; | |
| 335 input_method_config_view_map_["hangul"] = CreateLanguageHangulConfigView; | |
| 336 input_method_config_view_map_["mozc"] = CreateLanguageMozcConfigView; | |
| 337 input_method_config_view_map_["mozc-dv"] = CreateLanguageMozcConfigView; | |
| 338 input_method_config_view_map_["mozc-jp"] = CreateLanguageMozcConfigView; | |
| 339 input_method_config_view_map_["pinyin"] = CreateLanguagePinyinConfigView; | |
| 340 } | |
| 341 | |
| 342 void LanguageConfigView::OnAddLanguage(const std::string& language_code) { | |
| 343 // Skip if the language is already in the preferred_language_codes_. | |
| 344 if (model_.HasLanguageCode(language_code)) { | |
| 345 return; | |
| 346 } | |
| 347 // Activate the first input language associated with the language. We have | |
| 348 // to call this before the OnItemsAdded() call below so the checkbox | |
| 349 // for the first input language gets checked. | |
| 350 std::vector<std::string> input_method_ids; | |
| 351 model_.GetInputMethodIdsFromLanguageCode(language_code, &input_method_ids); | |
| 352 if (!input_method_ids.empty()) { | |
| 353 model_.SetInputMethodActivated(input_method_ids[0], true); | |
| 354 } | |
| 355 | |
| 356 // Append the language to the list of language codes. | |
| 357 const int added_at = model_.AddLanguageCode(language_code); | |
| 358 // Notify the table that the new row added at |added_at|. | |
| 359 preferred_language_table_->OnItemsAdded(added_at, 1); | |
| 360 // For some reason, OnItemsAdded() alone does not redraw the table. Need | |
| 361 // to tell the table that items are changed. TODO(satorux): Investigate | |
| 362 // if it's a bug in TableView2. | |
| 363 preferred_language_table_->OnItemsChanged( | |
| 364 0, model_.num_preferred_language_codes()); | |
| 365 // Switch to the row added. | |
| 366 preferred_language_table_->SelectRow(added_at); | |
| 367 | |
| 368 // Mark the language to be ignored. | |
| 369 add_language_combobox_model_->SetIgnored(language_code, true); | |
| 370 ResetAddLanguageCombobox(); | |
| 371 } | |
| 372 | |
| 373 void LanguageConfigView::OnRemoveLanguage() { | |
| 374 const int row = preferred_language_table_->GetFirstSelectedRow(); | |
| 375 const std::string& language_code = model_.preferred_language_code_at(row); | |
| 376 // Mark the language not to be ignored. | |
| 377 add_language_combobox_model_->SetIgnored(language_code, false); | |
| 378 ResetAddLanguageCombobox(); | |
| 379 // Deactivate the associated input methods. | |
| 380 model_.DeactivateInputMethodsFor(language_code); | |
| 381 // Remove the language code and the row from the table. | |
| 382 model_.RemoveLanguageAt(row); | |
| 383 preferred_language_table_->OnItemsRemoved(row, 1); | |
| 384 // Switch to the previous row, or the first row. | |
| 385 // There should be at least one row in the table. | |
| 386 preferred_language_table_->SelectRow(std::max(row - 1, 0)); | |
| 387 } | |
| 388 | |
| 389 void LanguageConfigView::ResetAddLanguageCombobox() { | |
| 390 // -1 to ignore "Add language". If there are more than one language, | |
| 391 // enable the combobox. Otherwise, disable it. | |
| 392 if (add_language_combobox_model_->GetItemCount() - 1 > 0) { | |
| 393 add_language_combobox_->SetEnabled(true); | |
| 394 } else { | |
| 395 add_language_combobox_->SetEnabled(false); | |
| 396 } | |
| 397 // Go back to the initial "Add language" state. | |
| 398 add_language_combobox_->ModelChanged(); | |
| 399 add_language_combobox_->SetSelectedItem(0); | |
| 400 } | |
| 401 | |
| 402 views::View* LanguageConfigView::CreateContentsOnLeft() { | |
| 403 views::View* contents = new views::View; | |
| 404 GridLayout* layout = new GridLayout(contents); | |
| 405 contents->SetLayoutManager(layout); | |
| 406 | |
| 407 // Set up column sets for the grid layout. | |
| 408 const int kTableColumnSetId = 0; | |
| 409 ColumnSet* column_set = layout->AddColumnSet(kTableColumnSetId); | |
| 410 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
| 411 GridLayout::USE_PREF, 0, 0); | |
| 412 | |
| 413 // Create the language table. | |
| 414 std::vector<TableColumn> columns; | |
| 415 TableColumn column(0, | |
| 416 l10n_util::GetStringUTF16( | |
| 417 IDS_OPTIONS_SETTINGS_LANGUAGES_LANGUAGES), | |
| 418 TableColumn::LEFT, -1, 0); | |
| 419 columns.push_back(column); | |
| 420 // We don't show horizontal and vertical lines. | |
| 421 const int options = (views::TableView2::SINGLE_SELECTION | | |
| 422 views::TableView2::RESIZABLE_COLUMNS | | |
| 423 views::TableView2::AUTOSIZE_COLUMNS); | |
| 424 preferred_language_table_ = | |
| 425 new views::TableView2(this, columns, views::TEXT_ONLY, options); | |
| 426 // Set the observer so OnSelectionChanged() will be invoked when a | |
| 427 // selection is changed in the table. | |
| 428 preferred_language_table_->SetObserver(this); | |
| 429 | |
| 430 // Add the language table. | |
| 431 layout->StartRow(1 /* expand vertically */, kTableColumnSetId); | |
| 432 layout->AddView(preferred_language_table_); | |
| 433 | |
| 434 return contents; | |
| 435 } | |
| 436 | |
| 437 views::View* LanguageConfigView::CreateContentsOnBottom() { | |
| 438 views::View* contents = new views::View; | |
| 439 GridLayout* layout = new GridLayout(contents); | |
| 440 contents->SetLayoutManager(layout); | |
| 441 | |
| 442 // Set up column sets for the grid layout. | |
| 443 const int kButtonsColumnSetId = 0; | |
| 444 ColumnSet* column_set = layout->AddColumnSet(kButtonsColumnSetId); | |
| 445 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 0, | |
| 446 GridLayout::USE_PREF, 0, 0); | |
| 447 column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); | |
| 448 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 0, | |
| 449 GridLayout::USE_PREF, 0, 0); | |
| 450 | |
| 451 // Create the add language combobox model_. | |
| 452 // LanguageComboboxModel sorts languages by their display names. | |
| 453 add_language_combobox_model_.reset( | |
| 454 new AddLanguageComboboxModel(NULL, model_.supported_language_codes())); | |
| 455 // Mark the existing preferred languages to be ignored. | |
| 456 for (size_t i = 0; i < model_.num_preferred_language_codes(); ++i) { | |
| 457 add_language_combobox_model_->SetIgnored( | |
| 458 model_.preferred_language_code_at(i), | |
| 459 true); | |
| 460 } | |
| 461 // Create the add language combobox. | |
| 462 add_language_combobox_ | |
| 463 = new views::Combobox(add_language_combobox_model_.get()); | |
| 464 add_language_combobox_->set_listener(this); | |
| 465 ResetAddLanguageCombobox(); | |
| 466 | |
| 467 // Create the remove button. | |
| 468 remove_language_button_ = new views::NativeButton( | |
| 469 this, UTF16ToWide(l10n_util::GetStringUTF16( | |
| 470 IDS_OPTIONS_SETTINGS_LANGUAGES_REMOVE_BUTTON))); | |
| 471 remove_language_button_->set_tag(kRemoveLanguageButton); | |
| 472 | |
| 473 // Add the add and remove buttons. | |
| 474 layout->StartRow(0, kButtonsColumnSetId); | |
| 475 layout->AddView(add_language_combobox_); | |
| 476 layout->AddView(remove_language_button_); | |
| 477 | |
| 478 return contents; | |
| 479 } | |
| 480 | |
| 481 views::View* LanguageConfigView::CreatePerLanguageConfigView( | |
| 482 const std::string& target_language_code) { | |
| 483 views::View* contents = new views::View; | |
| 484 GridLayout* layout = new GridLayout(contents); | |
| 485 contents->SetLayoutManager(layout); | |
| 486 | |
| 487 // Set up column sets for the grid layout. | |
| 488 ColumnSet* column_set = layout->AddColumnSet(kPerLanguageTitleColumnSetId); | |
| 489 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
| 490 GridLayout::USE_PREF, 0, 0); | |
| 491 | |
| 492 column_set = layout->AddColumnSet(kPerLanguageDoubleColumnSetId); | |
| 493 column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing); | |
| 494 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
| 495 GridLayout::USE_PREF, 0, 0); | |
| 496 column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); | |
| 497 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
| 498 GridLayout::USE_PREF, 0, 0); | |
| 499 | |
| 500 column_set = layout->AddColumnSet(kPerLanguageSingleColumnSetId); | |
| 501 column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing); | |
| 502 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, | |
| 503 GridLayout::USE_PREF, 0, 0); | |
| 504 | |
| 505 AddUiLanguageSection(target_language_code, layout); | |
| 506 layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); | |
| 507 AddInputMethodSection(target_language_code, layout); | |
| 508 | |
| 509 return contents; | |
| 510 } | |
| 511 | |
| 512 void LanguageConfigView::AddUiLanguageSection(const std::string& language_code, | |
| 513 views::GridLayout* layout) { | |
| 514 // Create the language name label. | |
| 515 const std::string application_locale = | |
| 516 g_browser_process->GetApplicationLocale(); | |
| 517 const string16 language_name16 = l10n_util::GetDisplayNameForLocale( | |
| 518 language_code, application_locale, true); | |
| 519 const std::wstring language_name = UTF16ToWide(language_name16); | |
| 520 views::Label* language_name_label = new views::Label(language_name); | |
| 521 language_name_label->SetFont( | |
| 522 language_name_label->font().DeriveFont(0, gfx::Font::BOLD)); | |
| 523 | |
| 524 // Add the language name label. | |
| 525 layout->StartRow(0, kPerLanguageTitleColumnSetId); | |
| 526 layout->AddView(language_name_label); | |
| 527 layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); | |
| 528 | |
| 529 layout->StartRow(0, kPerLanguageSingleColumnSetId); | |
| 530 if (application_locale == language_code) { | |
| 531 layout->AddView( | |
| 532 new views::Label( | |
| 533 UTF16ToWide(l10n_util::GetStringFUTF16( | |
| 534 IDS_OPTIONS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE, | |
| 535 l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME))))); | |
| 536 } else { | |
| 537 UiLanguageButton* button = new UiLanguageButton( | |
| 538 this, UTF16ToWide(l10n_util::GetStringFUTF16( | |
| 539 IDS_OPTIONS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE, | |
| 540 l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME))), | |
| 541 language_code); | |
| 542 button->set_tag(kChangeUiLanguageButton); | |
| 543 layout->AddView(button); | |
| 544 } | |
| 545 } | |
| 546 | |
| 547 void LanguageConfigView::AddInputMethodSection( | |
| 548 const std::string& language_code, | |
| 549 views::GridLayout* layout) { | |
| 550 // Create the input method title label. | |
| 551 views::Label* input_method_title_label = new views::Label( | |
| 552 UTF16ToWide(l10n_util::GetStringUTF16( | |
| 553 IDS_OPTIONS_SETTINGS_LANGUAGES_INPUT_METHOD))); | |
| 554 input_method_title_label->SetFont( | |
| 555 input_method_title_label->font().DeriveFont(0, gfx::Font::BOLD)); | |
| 556 | |
| 557 // Add the input method title label. | |
| 558 layout->StartRow(0, kPerLanguageTitleColumnSetId); | |
| 559 layout->AddView(input_method_title_label); | |
| 560 layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); | |
| 561 | |
| 562 // Add input method names and configuration buttons. | |
| 563 input_method_checkboxes_.clear(); | |
| 564 | |
| 565 // Get the list of input method ids associated with the language code. | |
| 566 std::vector<std::string> input_method_ids; | |
| 567 model_.GetInputMethodIdsFromLanguageCode(language_code, &input_method_ids); | |
| 568 | |
| 569 for (size_t i = 0; i < input_method_ids.size(); ++i) { | |
| 570 const std::string& input_method_id = input_method_ids[i]; | |
| 571 const std::string display_name = | |
| 572 input_method::GetInputMethodDisplayNameFromId(input_method_id); | |
| 573 layout->StartRow(0, kPerLanguageDoubleColumnSetId); | |
| 574 InputMethodCheckbox* checkbox | |
| 575 = new InputMethodCheckbox(UTF8ToWide(display_name), | |
| 576 input_method_id); | |
| 577 checkbox->set_listener(this); | |
| 578 checkbox->set_tag(kSelectInputMethodButton); | |
| 579 if (model_.InputMethodIsActivated(input_method_id)) { | |
| 580 checkbox->SetChecked(true); | |
| 581 } | |
| 582 | |
| 583 layout->AddView(checkbox); | |
| 584 input_method_checkboxes_.insert(checkbox); | |
| 585 // Add "configure" button for the input method if we have a | |
| 586 // configuration dialog for it. | |
| 587 if (input_method_config_view_map_.count(input_method_id) > 0) { | |
| 588 InputMethodButton* button = new InputMethodButton( | |
| 589 this, | |
| 590 UTF16ToWide(l10n_util::GetStringUTF16( | |
| 591 IDS_OPTIONS_SETTINGS_LANGUAGES_CONFIGURE)), | |
| 592 input_method_id); | |
| 593 button->set_tag(kConfigureInputMethodButton); | |
| 594 layout->AddView(button); | |
| 595 } | |
| 596 } | |
| 597 } | |
| 598 | |
| 599 views::DialogDelegate* LanguageConfigView::CreateInputMethodConfigureView( | |
| 600 const std::string& input_method_id) { | |
| 601 InputMethodConfigViewMap::const_iterator iter = | |
| 602 input_method_config_view_map_.find(input_method_id); | |
| 603 if (iter != input_method_config_view_map_.end()) { | |
| 604 CreateDialogDelegateFunction function = iter->second; | |
| 605 return function(profile()); | |
| 606 } | |
| 607 return NULL; | |
| 608 } | |
| 609 | |
| 610 void LanguageConfigView::MaybeDisableLastCheckbox() { | |
| 611 std::vector<std::string> input_method_ids; | |
| 612 model_.GetActiveInputMethodIds(&input_method_ids); | |
| 613 if (input_method_ids.size() <= 1) { | |
| 614 for (std::set<InputMethodCheckbox*>::iterator checkbox = | |
| 615 input_method_checkboxes_.begin(); | |
| 616 checkbox != input_method_checkboxes_.end(); ++checkbox) { | |
| 617 if ((*checkbox)->checked()) | |
| 618 (*checkbox)->SetEnabled(false); | |
| 619 } | |
| 620 } | |
| 621 } | |
| 622 | |
| 623 void LanguageConfigView::EnableAllCheckboxes() { | |
| 624 for (std::set<InputMethodCheckbox*>::iterator checkbox = | |
| 625 input_method_checkboxes_.begin(); | |
| 626 checkbox != input_method_checkboxes_.end(); ++checkbox) { | |
| 627 (*checkbox)->SetEnabled(true); | |
| 628 } | |
| 629 } | |
| 630 | |
| 631 } // namespace chromeos | |
| OLD | NEW |