| 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 "chrome/browser/gtk/options/languages_page_gtk.h" |
| 6 |
| 7 #include <set> |
| 8 #include <string> |
| 9 |
| 10 #include "app/l10n_util.h" |
| 11 #include "base/message_loop.h" |
| 12 #include "chrome/browser/browser_process.h" |
| 13 #include "chrome/browser/language_combobox_model.h" |
| 14 #include "chrome/browser/language_order_table_model.h" |
| 15 #include "chrome/common/gtk_util.h" |
| 16 #include "chrome/common/pref_names.h" |
| 17 #include "grit/generated_resources.h" |
| 18 |
| 19 namespace { |
| 20 |
| 21 const int kWrapWidth = 475; |
| 22 |
| 23 GtkWidget* NewComboboxFromModel(ComboboxModel* model) { |
| 24 GtkWidget* combobox = gtk_combo_box_new_text(); |
| 25 int count = model->GetItemCount(); |
| 26 for (int i = 0; i < count; ++i) |
| 27 gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), |
| 28 WideToUTF8(model->GetItemAt(i)).c_str()); |
| 29 return combobox; |
| 30 } |
| 31 |
| 32 //////////////////////////////////////////////////////////////////////////////// |
| 33 // AddLanguageDialog |
| 34 |
| 35 class AddLanguageDialog { |
| 36 public: |
| 37 AddLanguageDialog(Profile* profile, LanguagesPageGtk* delegate); |
| 38 private: |
| 39 // Callback for dialog buttons. |
| 40 static void OnResponse(GtkDialog* dialog, int response_id, |
| 41 AddLanguageDialog* window); |
| 42 |
| 43 // Callback for window destruction. |
| 44 static void OnWindowDestroy(GtkWidget* widget, AddLanguageDialog* window); |
| 45 |
| 46 // The dialog window. |
| 47 GtkWidget* dialog_; |
| 48 |
| 49 // The language chooser combobox. |
| 50 GtkWidget* combobox_; |
| 51 scoped_ptr<LanguageComboboxModel> accept_language_combobox_model_; |
| 52 |
| 53 // Used for call back to LanguagePageGtk that language has been selected. |
| 54 LanguagesPageGtk* language_delegate_; |
| 55 |
| 56 DISALLOW_COPY_AND_ASSIGN(AddLanguageDialog); |
| 57 }; |
| 58 |
| 59 AddLanguageDialog::AddLanguageDialog(Profile* profile, |
| 60 LanguagesPageGtk* delegate) |
| 61 : language_delegate_(delegate) { |
| 62 GtkWindow* parent = GTK_WINDOW( |
| 63 gtk_widget_get_toplevel(delegate->get_page_widget())); |
| 64 |
| 65 dialog_ = gtk_dialog_new_with_buttons( |
| 66 l10n_util::GetStringUTF8( |
| 67 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_TAB_TITLE).c_str(), |
| 68 parent, |
| 69 static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR), |
| 70 GTK_STOCK_CANCEL, |
| 71 GTK_RESPONSE_CANCEL, |
| 72 GTK_STOCK_ADD, |
| 73 GTK_RESPONSE_OK, |
| 74 NULL); |
| 75 gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_OK); |
| 76 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), |
| 77 gtk_util::kContentAreaSpacing); |
| 78 |
| 79 const std::string app_locale = g_browser_process->GetApplicationLocale(); |
| 80 std::vector<std::string> locale_codes; |
| 81 l10n_util::GetAcceptLanguagesForLocale(app_locale, &locale_codes); |
| 82 accept_language_combobox_model_.reset( |
| 83 new LanguageComboboxModel(profile, locale_codes)); |
| 84 combobox_ = NewComboboxFromModel(accept_language_combobox_model_.get()); |
| 85 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox_), 0); |
| 86 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), combobox_); |
| 87 |
| 88 g_signal_connect(dialog_, "response", G_CALLBACK(OnResponse), this); |
| 89 g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this); |
| 90 |
| 91 gtk_widget_show_all(dialog_); |
| 92 } |
| 93 |
| 94 // static |
| 95 void AddLanguageDialog::OnResponse(GtkDialog* dialog, |
| 96 int response_id, |
| 97 AddLanguageDialog* window) { |
| 98 if (response_id == GTK_RESPONSE_OK) { |
| 99 int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(window->combobox_)); |
| 100 window->language_delegate_->OnAddLanguage( |
| 101 window->accept_language_combobox_model_->GetLocaleFromIndex(selected)); |
| 102 } |
| 103 gtk_widget_destroy(window->dialog_); |
| 104 } |
| 105 |
| 106 // static |
| 107 void AddLanguageDialog::OnWindowDestroy(GtkWidget* widget, |
| 108 AddLanguageDialog* window) { |
| 109 MessageLoop::current()->DeleteSoon(FROM_HERE, window); |
| 110 } |
| 111 |
| 112 } // namespace |
| 113 |
| 114 //////////////////////////////////////////////////////////////////////////////// |
| 115 // LanguagesPageGtk |
| 116 |
| 117 LanguagesPageGtk::LanguagesPageGtk(Profile* profile) |
| 118 : OptionsPageBase(profile), initializing_(true) { |
| 119 Init(); |
| 120 } |
| 121 |
| 122 LanguagesPageGtk::~LanguagesPageGtk() { |
| 123 } |
| 124 |
| 125 void LanguagesPageGtk::Init() { |
| 126 page_ = gtk_vbox_new(FALSE, gtk_util::kContentAreaSpacing); |
| 127 gtk_container_set_border_width(GTK_CONTAINER(page_), |
| 128 gtk_util::kContentAreaBorder); |
| 129 |
| 130 // Languages order controls. |
| 131 GtkWidget* languages_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |
| 132 gtk_box_pack_start(GTK_BOX(page_), languages_vbox, |
| 133 TRUE, TRUE, 0); |
| 134 |
| 135 GtkWidget* languages_instructions_label = gtk_label_new( |
| 136 l10n_util::GetStringUTF8( |
| 137 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_INSTRUCTIONS).c_str()); |
| 138 gtk_misc_set_alignment(GTK_MISC(languages_instructions_label), 0, .5); |
| 139 gtk_label_set_line_wrap(GTK_LABEL(languages_instructions_label), TRUE); |
| 140 gtk_widget_set_size_request(languages_instructions_label, kWrapWidth, -1); |
| 141 gtk_box_pack_start(GTK_BOX(languages_vbox), languages_instructions_label, |
| 142 FALSE, FALSE, 0); |
| 143 |
| 144 GtkWidget* languages_list_hbox = gtk_hbox_new(FALSE, |
| 145 gtk_util::kControlSpacing); |
| 146 gtk_box_pack_start(GTK_BOX(languages_vbox), languages_list_hbox, |
| 147 TRUE, TRUE, 0); |
| 148 |
| 149 // Languages order tree. |
| 150 language_order_store_ = gtk_list_store_new(COL_COUNT, |
| 151 G_TYPE_STRING); |
| 152 language_order_tree_ = gtk_tree_view_new_with_model( |
| 153 GTK_TREE_MODEL(language_order_store_)); |
| 154 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(language_order_tree_), FALSE); |
| 155 GtkTreeViewColumn* lang_column = gtk_tree_view_column_new_with_attributes( |
| 156 "", |
| 157 gtk_cell_renderer_text_new(), |
| 158 "text", COL_LANG, |
| 159 NULL); |
| 160 gtk_tree_view_append_column(GTK_TREE_VIEW(language_order_tree_), lang_column); |
| 161 language_order_selection_ = gtk_tree_view_get_selection( |
| 162 GTK_TREE_VIEW(language_order_tree_)); |
| 163 gtk_tree_selection_set_mode(language_order_selection_, |
| 164 GTK_SELECTION_MULTIPLE); |
| 165 g_signal_connect(G_OBJECT(language_order_selection_), "changed", |
| 166 G_CALLBACK(OnSelectionChanged), this); |
| 167 GtkWidget* scroll_window = gtk_scrolled_window_new(NULL, NULL); |
| 168 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), |
| 169 GTK_POLICY_AUTOMATIC, |
| 170 GTK_POLICY_AUTOMATIC); |
| 171 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll_window), |
| 172 GTK_SHADOW_ETCHED_IN); |
| 173 gtk_container_add(GTK_CONTAINER(scroll_window), language_order_tree_); |
| 174 gtk_box_pack_start(GTK_BOX(languages_list_hbox), scroll_window, |
| 175 TRUE, TRUE, 0); |
| 176 |
| 177 language_order_table_model_.reset(new LanguageOrderTableModel); |
| 178 language_order_table_adapter_.reset( |
| 179 new gtk_tree::ModelAdapter(this, language_order_store_, |
| 180 language_order_table_model_.get())); |
| 181 |
| 182 // Languages order buttons. |
| 183 GtkWidget* languages_buttons_vbox = gtk_vbox_new(FALSE, |
| 184 gtk_util::kControlSpacing); |
| 185 gtk_box_pack_start(GTK_BOX(languages_list_hbox), languages_buttons_vbox, |
| 186 FALSE, FALSE, 0); |
| 187 |
| 188 add_button_ = gtk_button_new_with_label(l10n_util::GetStringUTF8( |
| 189 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_ADD_BUTTON_LABEL).c_str()); |
| 190 g_signal_connect(G_OBJECT(add_button_), "clicked", |
| 191 G_CALLBACK(OnAddButtonClicked), this); |
| 192 gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), add_button_, |
| 193 FALSE, FALSE, 0); |
| 194 |
| 195 std::string remove_button_text = l10n_util::GetStringUTF8( |
| 196 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_REMOVE_BUTTON_LABEL); |
| 197 remove_button_ = gtk_button_new_with_label(remove_button_text.c_str()); |
| 198 g_signal_connect(G_OBJECT(remove_button_), "clicked", |
| 199 G_CALLBACK(OnRemoveButtonClicked), this); |
| 200 gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), remove_button_, |
| 201 FALSE, FALSE, 0); |
| 202 |
| 203 std::string move_up_button_text = l10n_util::GetStringUTF8( |
| 204 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_MOVEUP_BUTTON_LABEL); |
| 205 move_up_button_ = gtk_button_new_with_label(move_up_button_text.c_str()); |
| 206 g_signal_connect(G_OBJECT(move_up_button_), "clicked", |
| 207 G_CALLBACK(OnMoveUpButtonClicked), this); |
| 208 gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), move_up_button_, |
| 209 FALSE, FALSE, 0); |
| 210 |
| 211 std::string move_down_button_text = l10n_util::GetStringUTF8( |
| 212 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_MOVEDOWN_BUTTON_LABEL); |
| 213 move_down_button_ = gtk_button_new_with_label(move_down_button_text.c_str()); |
| 214 g_signal_connect(G_OBJECT(move_down_button_), "clicked", |
| 215 G_CALLBACK(OnMoveDownButtonClicked), this); |
| 216 gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), move_down_button_, |
| 217 FALSE, FALSE, 0); |
| 218 |
| 219 GtkWidget* spellchecker_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); |
| 220 gtk_box_pack_start(GTK_BOX(page_), spellchecker_vbox, |
| 221 FALSE, FALSE, 0); |
| 222 |
| 223 // TODO(mattm): Spell checker controls. |
| 224 |
| 225 // Initialize. |
| 226 accept_languages_.Init(prefs::kAcceptLanguages, |
| 227 profile()->GetPrefs(), this); |
| 228 dictionary_language_.Init(prefs::kSpellCheckDictionary, |
| 229 profile()->GetPrefs(), this); |
| 230 enable_spellcheck_.Init(prefs::kEnableSpellCheck, |
| 231 profile()->GetPrefs(), this); |
| 232 enable_autospellcorrect_.Init(prefs::kEnableAutoSpellCorrect, |
| 233 profile()->GetPrefs(), this); |
| 234 NotifyPrefChanged(NULL); |
| 235 EnableControls(); |
| 236 } |
| 237 |
| 238 void LanguagesPageGtk::SetColumnValues(int row, GtkTreeIter* iter) { |
| 239 std::wstring lang = language_order_table_model_->GetText(row, 0); |
| 240 gtk_list_store_set(language_order_store_, iter, |
| 241 COL_LANG, WideToUTF8(lang).c_str(), |
| 242 -1); |
| 243 } |
| 244 |
| 245 void LanguagesPageGtk::OnAnyModelUpdate() { |
| 246 if (!initializing_) { |
| 247 accept_languages_.SetValue(ASCIIToWide( |
| 248 language_order_table_model_->GetLanguageList())); |
| 249 } |
| 250 EnableControls(); |
| 251 } |
| 252 |
| 253 void LanguagesPageGtk::EnableControls() { |
| 254 int num_selected = gtk_tree_selection_count_selected_rows( |
| 255 language_order_selection_); |
| 256 int row_count = gtk_tree_model_iter_n_children( |
| 257 GTK_TREE_MODEL(language_order_store_), NULL); |
| 258 gtk_widget_set_sensitive(move_up_button_, |
| 259 num_selected == 1 && FirstSelectedRowNum() > 0); |
| 260 gtk_widget_set_sensitive(move_down_button_, |
| 261 num_selected == 1 && |
| 262 FirstSelectedRowNum() < row_count - 1); |
| 263 gtk_widget_set_sensitive(remove_button_, num_selected > 0); |
| 264 } |
| 265 |
| 266 int LanguagesPageGtk::FirstSelectedRowNum() { |
| 267 int row_num = -1; |
| 268 GList* list = gtk_tree_selection_get_selected_rows(language_order_selection_, |
| 269 NULL); |
| 270 if (list) { |
| 271 row_num = gtk_tree::GetRowNumForPath(static_cast<GtkTreePath*>(list->data)); |
| 272 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL); |
| 273 g_list_free(list); |
| 274 } |
| 275 return row_num; |
| 276 } |
| 277 |
| 278 void LanguagesPageGtk::NotifyPrefChanged(const std::wstring* pref_name) { |
| 279 initializing_ = true; |
| 280 if (!pref_name || *pref_name == prefs::kAcceptLanguages) { |
| 281 language_order_table_model_->SetAcceptLanguagesString( |
| 282 WideToASCII(accept_languages_.GetValue())); |
| 283 } |
| 284 // TODO(mattm): Spell checker prefs. |
| 285 initializing_ = false; |
| 286 } |
| 287 |
| 288 void LanguagesPageGtk::OnAddLanguage(const std::string& new_language) { |
| 289 if (language_order_table_model_->Add(new_language)) |
| 290 gtk_tree::SelectAndFocusRowNum(language_order_table_model_->RowCount() - 1, |
| 291 GTK_TREE_VIEW(language_order_tree_)); |
| 292 } |
| 293 |
| 294 // static |
| 295 void LanguagesPageGtk::OnSelectionChanged(GtkTreeSelection *selection, |
| 296 LanguagesPageGtk* languages_page) { |
| 297 languages_page->EnableControls(); |
| 298 } |
| 299 |
| 300 // static |
| 301 void LanguagesPageGtk::OnAddButtonClicked(GtkButton* button, |
| 302 LanguagesPageGtk* languages_page) { |
| 303 new AddLanguageDialog(languages_page->profile(), languages_page); |
| 304 } |
| 305 |
| 306 // static |
| 307 void LanguagesPageGtk::OnRemoveButtonClicked(GtkButton* button, |
| 308 LanguagesPageGtk* languages_page) { |
| 309 GList* list = gtk_tree_selection_get_selected_rows( |
| 310 languages_page->language_order_selection_, NULL); |
| 311 std::set<int> selected_rows; |
| 312 GList* node; |
| 313 for (node = list; node != NULL; node = node->next) { |
| 314 selected_rows.insert( |
| 315 gtk_tree::GetRowNumForPath(static_cast<GtkTreePath*>(node->data))); |
| 316 } |
| 317 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL); |
| 318 g_list_free(list); |
| 319 |
| 320 for (std::set<int>::reverse_iterator selected = selected_rows.rbegin(); |
| 321 selected != selected_rows.rend(); ++selected) { |
| 322 languages_page->language_order_table_model_->Remove(*selected); |
| 323 } |
| 324 } |
| 325 |
| 326 // static |
| 327 void LanguagesPageGtk::OnMoveUpButtonClicked(GtkButton* button, |
| 328 LanguagesPageGtk* languages_page) { |
| 329 int item_selected = languages_page->FirstSelectedRowNum(); |
| 330 languages_page->language_order_table_model_->MoveUp(item_selected); |
| 331 gtk_tree::SelectAndFocusRowNum( |
| 332 item_selected - 1, GTK_TREE_VIEW(languages_page->language_order_tree_)); |
| 333 } |
| 334 |
| 335 // static |
| 336 void LanguagesPageGtk::OnMoveDownButtonClicked( |
| 337 GtkButton* button, LanguagesPageGtk* languages_page) { |
| 338 int item_selected = languages_page->FirstSelectedRowNum(); |
| 339 languages_page->language_order_table_model_->MoveDown(item_selected); |
| 340 gtk_tree::SelectAndFocusRowNum( |
| 341 item_selected + 1, GTK_TREE_VIEW(languages_page->language_order_tree_)); |
| 342 } |
| OLD | NEW |