Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(652)

Side by Side Diff: chrome/browser/gtk/options/languages_page_gtk.cc

Issue 6251001: Move chrome/browser/gtk/ to chrome/browser/ui/gtk/... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 #include <vector>
10
11 #include "app/gtk_signal.h"
12 #include "app/l10n_util.h"
13 #include "base/command_line.h"
14 #include "base/message_loop.h"
15 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/gtk/gtk_util.h"
18 #include "chrome/browser/language_combobox_model.h"
19 #include "chrome/browser/language_order_table_model.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/common/spellcheck_common.h"
24 #include "grit/generated_resources.h"
25
26 namespace {
27
28 const int kWrapWidth = 475;
29
30 GtkWidget* NewComboboxFromModel(ComboboxModel* model) {
31 GtkWidget* combobox = gtk_combo_box_new_text();
32 int count = model->GetItemCount();
33 for (int i = 0; i < count; ++i)
34 gtk_combo_box_append_text(GTK_COMBO_BOX(combobox),
35 UTF16ToUTF8(model->GetItemAt(i)).c_str());
36 return combobox;
37 }
38
39 ////////////////////////////////////////////////////////////////////////////////
40 // AddLanguageDialog
41
42 class AddLanguageDialog {
43 public:
44 AddLanguageDialog(Profile* profile, LanguagesPageGtk* delegate);
45 virtual ~AddLanguageDialog() {}
46
47 private:
48 // Callback for dialog buttons.
49 CHROMEGTK_CALLBACK_1(AddLanguageDialog, void, OnResponse, int);
50
51 // Callback for window destruction.
52 CHROMEGTK_CALLBACK_0(AddLanguageDialog, void, OnWindowDestroy);
53
54 // The dialog window.
55 GtkWidget* dialog_;
56
57 // The language chooser combobox.
58 GtkWidget* combobox_;
59 scoped_ptr<LanguageComboboxModel> accept_language_combobox_model_;
60
61 // Used for call back to LanguagePageGtk that language has been selected.
62 LanguagesPageGtk* language_delegate_;
63
64 DISALLOW_COPY_AND_ASSIGN(AddLanguageDialog);
65 };
66
67 AddLanguageDialog::AddLanguageDialog(Profile* profile,
68 LanguagesPageGtk* delegate)
69 : language_delegate_(delegate) {
70 GtkWindow* parent = GTK_WINDOW(
71 gtk_widget_get_toplevel(delegate->get_page_widget()));
72
73 dialog_ = gtk_dialog_new_with_buttons(
74 l10n_util::GetStringUTF8(
75 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_TAB_TITLE).c_str(),
76 parent,
77 static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
78 GTK_STOCK_CANCEL,
79 GTK_RESPONSE_CANCEL,
80 GTK_STOCK_ADD,
81 GTK_RESPONSE_OK,
82 NULL);
83 gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_OK);
84 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
85 gtk_util::kContentAreaSpacing);
86
87 const std::string app_locale = g_browser_process->GetApplicationLocale();
88 std::vector<std::string> locale_codes;
89 l10n_util::GetAcceptLanguagesForLocale(app_locale, &locale_codes);
90 accept_language_combobox_model_.reset(
91 new LanguageComboboxModel(profile, locale_codes));
92 combobox_ = NewComboboxFromModel(accept_language_combobox_model_.get());
93 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox_), 0);
94 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), combobox_);
95
96 g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
97 g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroyThunk), this);
98
99 gtk_util::ShowDialog(dialog_);
100 }
101
102 void AddLanguageDialog::OnResponse(GtkWidget* dialog, int response_id) {
103 if (response_id == GTK_RESPONSE_OK) {
104 int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(combobox_));
105 language_delegate_->OnAddLanguage(
106 accept_language_combobox_model_->GetLocaleFromIndex(selected));
107 }
108 gtk_widget_destroy(dialog_);
109 }
110
111 void AddLanguageDialog::OnWindowDestroy(GtkWidget* widget) {
112 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
113 }
114
115 } // namespace
116
117 ////////////////////////////////////////////////////////////////////////////////
118 // LanguagesPageGtk
119
120 LanguagesPageGtk::LanguagesPageGtk(Profile* profile)
121 : OptionsPageBase(profile),
122 enable_autospellcorrect_checkbox_(NULL),
123 initializing_(true) {
124 Init();
125 }
126
127 LanguagesPageGtk::~LanguagesPageGtk() {
128 }
129
130 void LanguagesPageGtk::Init() {
131 page_ = gtk_vbox_new(FALSE, gtk_util::kContentAreaSpacing);
132 gtk_container_set_border_width(GTK_CONTAINER(page_),
133 gtk_util::kContentAreaBorder);
134
135 // Languages order controls.
136 GtkWidget* languages_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
137 gtk_box_pack_start(GTK_BOX(page_), languages_vbox,
138 TRUE, TRUE, 0);
139
140 GtkWidget* languages_instructions_label = gtk_label_new(
141 l10n_util::GetStringUTF8(
142 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_INSTRUCTIONS).c_str());
143 gtk_misc_set_alignment(GTK_MISC(languages_instructions_label), 0, .5);
144 gtk_util::SetLabelWidth(languages_instructions_label, kWrapWidth);
145 gtk_box_pack_start(GTK_BOX(languages_vbox), languages_instructions_label,
146 FALSE, FALSE, 0);
147
148 GtkWidget* languages_list_hbox = gtk_hbox_new(FALSE,
149 gtk_util::kControlSpacing);
150 gtk_box_pack_start(GTK_BOX(languages_vbox), languages_list_hbox,
151 TRUE, TRUE, 0);
152
153 // Languages order tree.
154 language_order_store_ = gtk_list_store_new(COL_COUNT,
155 G_TYPE_STRING);
156 language_order_tree_ = gtk_tree_view_new_with_model(
157 GTK_TREE_MODEL(language_order_store_));
158 g_object_unref(language_order_store_);
159 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(language_order_tree_), FALSE);
160 GtkTreeViewColumn* lang_column = gtk_tree_view_column_new_with_attributes(
161 "",
162 gtk_cell_renderer_text_new(),
163 "text", COL_LANG,
164 NULL);
165 gtk_tree_view_append_column(GTK_TREE_VIEW(language_order_tree_), lang_column);
166 language_order_selection_ = gtk_tree_view_get_selection(
167 GTK_TREE_VIEW(language_order_tree_));
168 gtk_tree_selection_set_mode(language_order_selection_,
169 GTK_SELECTION_MULTIPLE);
170 g_signal_connect(language_order_selection_, "changed",
171 G_CALLBACK(OnSelectionChangedThunk), this);
172 GtkWidget* scroll_window = gtk_scrolled_window_new(NULL, NULL);
173 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window),
174 GTK_POLICY_AUTOMATIC,
175 GTK_POLICY_AUTOMATIC);
176 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll_window),
177 GTK_SHADOW_ETCHED_IN);
178 gtk_container_add(GTK_CONTAINER(scroll_window), language_order_tree_);
179 gtk_box_pack_start(GTK_BOX(languages_list_hbox), scroll_window,
180 TRUE, TRUE, 0);
181
182 language_order_table_model_.reset(new LanguageOrderTableModel);
183 language_order_table_adapter_.reset(
184 new gtk_tree::TableAdapter(this, language_order_store_,
185 language_order_table_model_.get()));
186
187 // Languages order buttons.
188 GtkWidget* languages_buttons_vbox = gtk_vbox_new(FALSE,
189 gtk_util::kControlSpacing);
190 gtk_box_pack_start(GTK_BOX(languages_list_hbox), languages_buttons_vbox,
191 FALSE, FALSE, 0);
192
193 add_button_ = gtk_button_new_with_label(l10n_util::GetStringUTF8(
194 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_ADD_BUTTON_LABEL).c_str());
195 g_signal_connect(add_button_, "clicked",
196 G_CALLBACK(OnAddButtonClickedThunk), this);
197 gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), add_button_,
198 FALSE, FALSE, 0);
199
200 std::string remove_button_text = l10n_util::GetStringUTF8(
201 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_REMOVE_BUTTON_LABEL);
202 remove_button_ = gtk_button_new_with_label(remove_button_text.c_str());
203 g_signal_connect(remove_button_, "clicked",
204 G_CALLBACK(OnRemoveButtonClickedThunk), this);
205 gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), remove_button_,
206 FALSE, FALSE, 0);
207
208 std::string move_up_button_text = l10n_util::GetStringUTF8(
209 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_MOVEUP_BUTTON_LABEL);
210 move_up_button_ = gtk_button_new_with_label(move_up_button_text.c_str());
211 g_signal_connect(move_up_button_, "clicked",
212 G_CALLBACK(OnMoveUpButtonClickedThunk), this);
213 gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), move_up_button_,
214 FALSE, FALSE, 0);
215
216 std::string move_down_button_text = l10n_util::GetStringUTF8(
217 IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_MOVEDOWN_BUTTON_LABEL);
218 move_down_button_ = gtk_button_new_with_label(move_down_button_text.c_str());
219 g_signal_connect(move_down_button_, "clicked",
220 G_CALLBACK(OnMoveDownButtonClickedThunk), this);
221 gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), move_down_button_,
222 FALSE, FALSE, 0);
223
224 // Spell checker controls.
225 GtkWidget* spellchecker_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
226 gtk_box_pack_start(GTK_BOX(page_), spellchecker_vbox,
227 FALSE, FALSE, 0);
228
229 enable_spellchecking_checkbox_ = gtk_check_button_new_with_label(
230 l10n_util::GetStringUTF8(IDS_OPTIONS_ENABLE_SPELLCHECK).c_str());
231 g_signal_connect(enable_spellchecking_checkbox_, "toggled",
232 G_CALLBACK(OnEnableSpellCheckingToggledThunk), this);
233 gtk_box_pack_start(GTK_BOX(spellchecker_vbox), enable_spellchecking_checkbox_,
234 FALSE, FALSE, 0);
235
236 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
237 if (command_line.HasSwitch(switches::kExperimentalSpellcheckerFeatures)) {
238 enable_autospellcorrect_checkbox_ = gtk_check_button_new_with_label(
239 l10n_util::GetStringUTF8(
240 IDS_OPTIONS_ENABLE_AUTO_SPELL_CORRECTION).c_str());
241 g_signal_connect(enable_autospellcorrect_checkbox_, "toggled",
242 G_CALLBACK(OnEnableAutoSpellCheckingToggledThunk), this);
243 gtk_box_pack_start(GTK_BOX(spellchecker_vbox),
244 enable_autospellcorrect_checkbox_, FALSE, FALSE, 0);
245 }
246
247 std::vector<std::string> spell_check_languages;
248 SpellCheckCommon::SpellCheckLanguages(&spell_check_languages);
249 dictionary_language_model_.reset(new LanguageComboboxModel(profile(),
250 spell_check_languages));
251 dictionary_language_combobox_ = NewComboboxFromModel(
252 dictionary_language_model_.get());
253 g_signal_connect(dictionary_language_combobox_, "changed",
254 G_CALLBACK(OnDictionaryLanguageChangedThunk), this);
255 GtkWidget* dictionary_language_control =
256 gtk_util::CreateLabeledControlsGroup(NULL,
257 l10n_util::GetStringUTF8(
258 IDS_OPTIONS_CHROME_DICTIONARY_LANGUAGE).c_str(),
259 dictionary_language_combobox_,
260 NULL);
261 gtk_box_pack_start(GTK_BOX(spellchecker_vbox), dictionary_language_control,
262 FALSE, FALSE, 0);
263
264 // Initialize.
265 accept_languages_.Init(prefs::kAcceptLanguages,
266 profile()->GetPrefs(), this);
267 dictionary_language_.Init(prefs::kSpellCheckDictionary,
268 profile()->GetPrefs(), this);
269 enable_spellcheck_.Init(prefs::kEnableSpellCheck,
270 profile()->GetPrefs(), this);
271 enable_autospellcorrect_.Init(prefs::kEnableAutoSpellCorrect,
272 profile()->GetPrefs(), this);
273 NotifyPrefChanged(NULL);
274 EnableControls();
275 }
276
277 void LanguagesPageGtk::SetColumnValues(int row, GtkTreeIter* iter) {
278 string16 lang = language_order_table_model_->GetText(row, 0);
279 gtk_list_store_set(language_order_store_, iter,
280 COL_LANG, UTF16ToUTF8(lang).c_str(),
281 -1);
282 }
283
284 void LanguagesPageGtk::OnAnyModelUpdate() {
285 if (!initializing_)
286 accept_languages_.SetValue(language_order_table_model_->GetLanguageList());
287 EnableControls();
288 }
289
290 void LanguagesPageGtk::EnableControls() {
291 int num_selected = gtk_tree_selection_count_selected_rows(
292 language_order_selection_);
293 int row_count = gtk_tree_model_iter_n_children(
294 GTK_TREE_MODEL(language_order_store_), NULL);
295 gtk_widget_set_sensitive(move_up_button_,
296 num_selected == 1 && FirstSelectedRowNum() > 0);
297 gtk_widget_set_sensitive(move_down_button_,
298 num_selected == 1 &&
299 FirstSelectedRowNum() < row_count - 1);
300 gtk_widget_set_sensitive(remove_button_, num_selected > 0);
301 }
302
303 int LanguagesPageGtk::FirstSelectedRowNum() {
304 int row_num = -1;
305 GList* list = gtk_tree_selection_get_selected_rows(language_order_selection_,
306 NULL);
307 if (list) {
308 row_num = gtk_tree::GetRowNumForPath(static_cast<GtkTreePath*>(list->data));
309 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
310 g_list_free(list);
311 }
312 return row_num;
313 }
314
315 void LanguagesPageGtk::NotifyPrefChanged(const std::string* pref_name) {
316 initializing_ = true;
317 if (!pref_name || *pref_name == prefs::kAcceptLanguages) {
318 language_order_table_model_->SetAcceptLanguagesString(
319 accept_languages_.GetValue());
320 }
321 if (!pref_name || *pref_name == prefs::kSpellCheckDictionary) {
322 int index = dictionary_language_model_->GetSelectedLanguageIndex(
323 prefs::kSpellCheckDictionary);
324
325 // If not found, fall back from "language-region" to "language".
326 if (index < 0) {
327 const std::string& lang_region = dictionary_language_.GetValue();
328 dictionary_language_.SetValue(
329 SpellCheckCommon::GetLanguageFromLanguageRegion(lang_region));
330 index = dictionary_language_model_->GetSelectedLanguageIndex(
331 prefs::kSpellCheckDictionary);
332 }
333
334 gtk_combo_box_set_active(GTK_COMBO_BOX(dictionary_language_combobox_),
335 index);
336 }
337 if (!pref_name || *pref_name == prefs::kEnableSpellCheck) {
338 gtk_toggle_button_set_active(
339 GTK_TOGGLE_BUTTON(enable_spellchecking_checkbox_),
340 enable_spellcheck_.GetValue());
341 }
342 if (!pref_name || *pref_name == prefs::kEnableAutoSpellCorrect) {
343 if (enable_autospellcorrect_checkbox_) {
344 gtk_toggle_button_set_active(
345 GTK_TOGGLE_BUTTON(enable_autospellcorrect_checkbox_),
346 enable_autospellcorrect_.GetValue());
347 }
348 }
349 initializing_ = false;
350 }
351
352 void LanguagesPageGtk::OnAddLanguage(const std::string& new_language) {
353 if (language_order_table_model_->Add(new_language))
354 gtk_tree::SelectAndFocusRowNum(language_order_table_model_->RowCount() - 1,
355 GTK_TREE_VIEW(language_order_tree_));
356 }
357
358 void LanguagesPageGtk::OnSelectionChanged(GtkTreeSelection* selection) {
359 EnableControls();
360 }
361
362 void LanguagesPageGtk::OnAddButtonClicked(GtkWidget* button) {
363 new AddLanguageDialog(profile(), this);
364 }
365
366 void LanguagesPageGtk::OnRemoveButtonClicked(GtkWidget* button) {
367 std::set<int> selected_rows;
368 gtk_tree::GetSelectedIndices(language_order_selection_,
369 &selected_rows);
370
371 int selected_row = 0;
372 for (std::set<int>::reverse_iterator selected = selected_rows.rbegin();
373 selected != selected_rows.rend(); ++selected) {
374 language_order_table_model_->Remove(*selected);
375 selected_row = *selected;
376 }
377 int row_count = language_order_table_model_->RowCount();
378 if (row_count <= 0)
379 return;
380 if (selected_row >= row_count)
381 selected_row = row_count - 1;
382 gtk_tree::SelectAndFocusRowNum(selected_row,
383 GTK_TREE_VIEW(language_order_tree_));
384 }
385
386 void LanguagesPageGtk::OnMoveUpButtonClicked(GtkWidget* button) {
387 int item_selected = FirstSelectedRowNum();
388 language_order_table_model_->MoveUp(item_selected);
389 gtk_tree::SelectAndFocusRowNum(
390 item_selected - 1, GTK_TREE_VIEW(language_order_tree_));
391 }
392
393 void LanguagesPageGtk::OnMoveDownButtonClicked(GtkWidget* button) {
394 int item_selected = FirstSelectedRowNum();
395 language_order_table_model_->MoveDown(item_selected);
396 gtk_tree::SelectAndFocusRowNum(
397 item_selected + 1, GTK_TREE_VIEW(language_order_tree_));
398 }
399
400 void LanguagesPageGtk::OnEnableSpellCheckingToggled(GtkWidget* toggle_button) {
401 if (initializing_)
402 return;
403 enable_spellcheck_.SetValue(
404 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button)));
405 }
406
407 void LanguagesPageGtk::OnEnableAutoSpellCheckingToggled(
408 GtkWidget* toggle_button) {
409 if (initializing_)
410 return;
411 enable_autospellcorrect_.SetValue(
412 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button)));
413 }
414
415 void LanguagesPageGtk::OnDictionaryLanguageChanged(GtkWidget* widget) {
416 if (initializing_)
417 return;
418 int new_index = gtk_combo_box_get_active(
419 GTK_COMBO_BOX(dictionary_language_combobox_));
420
421 if (new_index < 0 ||
422 new_index >= dictionary_language_model_->GetItemCount()) {
423 NOTREACHED();
424 return;
425 }
426
427 // Remove the previously added spell check language to the accept list.
428 if (!spellcheck_language_added_.empty()) {
429 int old_index = language_order_table_model_->GetIndex(
430 spellcheck_language_added_);
431 if (old_index > -1)
432 language_order_table_model_->Remove(old_index);
433 }
434
435 // Add this new spell check language only if it is not already in the
436 // accept language list.
437 std::string language =
438 dictionary_language_model_->GetLocaleFromIndex(new_index);
439 int index = language_order_table_model_->GetIndex(language);
440 if (index == -1) {
441 // Add the new language.
442 OnAddLanguage(language);
443 spellcheck_language_added_ = language;
444 } else {
445 spellcheck_language_added_ = "";
446 }
447
448 UserMetricsRecordAction(UserMetricsAction("Options_DictionaryLanguage"),
449 profile()->GetPrefs());
450 dictionary_language_.SetValue(language);
451 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/options/languages_page_gtk.h ('k') | chrome/browser/gtk/options/languages_page_gtk_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698