summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-19 04:48:24 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-19 04:48:24 +0000
commit65705eaa06155250c255ecdb766ebfeb081025f7 (patch)
treec49d0fc18479349f09643423c5b2f5862a0a33c6
parent1a6b30a619cba771cb9c4ed4da9c3778634567ad (diff)
downloadchromium_src-65705eaa06155250c255ecdb766ebfeb081025f7.zip
chromium_src-65705eaa06155250c255ecdb766ebfeb081025f7.tar.gz
chromium_src-65705eaa06155250c255ecdb766ebfeb081025f7.tar.bz2
Gtk languages options page part 1: accept-languages configuration.
Move accept_language_list to l10n_util, use it for LanguagesPageGtk. BUG=13524 TEST=You can view, reorder, remove and add accept-languages. Review URL: http://codereview.chromium.org/174043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23695 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--app/l10n_util.cc153
-rw-r--r--app/l10n_util.h4
-rw-r--r--chrome/browser/gtk/options/fonts_languages_window_gtk.cc9
-rw-r--r--chrome/browser/gtk/options/languages_page_gtk.cc342
-rw-r--r--chrome/browser/gtk/options/languages_page_gtk.h115
-rw-r--r--chrome/browser/gtk/options/languages_page_gtk_unittest.cc226
-rw-r--r--chrome/browser/language_order_table_model.cc7
-rw-r--r--chrome/browser/language_order_table_model.h4
-rw-r--r--chrome/browser/views/options/languages_page_view.cc159
-rw-r--r--chrome/chrome.gyp3
-rw-r--r--chrome/test/data/valgrind/unit_tests.gtest_linux.txt1
11 files changed, 864 insertions, 159 deletions
diff --git a/app/l10n_util.cc b/app/l10n_util.cc
index 0e263b6de..d22425b 100644
--- a/app/l10n_util.cc
+++ b/app/l10n_util.cc
@@ -39,6 +39,141 @@ static const FilePath::CharType kLocaleFileExtension[] = ".pak";
// Added to the end of strings that are too big in TrucateString.
static const wchar_t* const kElideString = L"\x2026";
+static const char* const kAcceptLanguageList[] = {
+ "af", // Afrikaans
+ "am", // Amharic
+ "ar", // Arabic
+ "az", // Azerbaijani
+ "be", // Belarusian
+ "bg", // Bulgarian
+ "bh", // Bihari
+ "bn", // Bengali
+ "br", // Breton
+ "bs", // Bosnian
+ "ca", // Catalan
+ "co", // Corsican
+ "cs", // Czech
+ "cy", // Welsh
+ "da", // Danish
+ "de", // German
+ "de-AT", // German (Austria)
+ "de-CH", // German (Switzerland)
+ "de-DE", // German (Germany)
+ "el", // Greek
+ "en", // English
+ "en-AU", // English (Austrailia)
+ "en-CA", // English (Canada)
+ "en-GB", // English (UK)
+ "en-NZ", // English (New Zealand)
+ "en-US", // English (US)
+ "en-ZA", // English (South Africa)
+ "eo", // Esperanto
+ // TODO(jungshik) : Do we want to list all es-Foo for Latin-American
+ // Spanish speaking countries?
+ "es", // Spanish
+ "et", // Estonian
+ "eu", // Basque
+ "fa", // Persian
+ "fi", // Finnish
+ "fil", // Filipino
+ "fo", // Faroese
+ "fr", // French
+ "fr-CA", // French (Canada)
+ "fr-CH", // French (Switzerland)
+ "fr-FR", // French (France)
+ "fy", // Frisian
+ "ga", // Irish
+ "gd", // Scots Gaelic
+ "gl", // Galician
+ "gn", // Guarani
+ "gu", // Gujarati
+ "he", // Hebrew
+ "hi", // Hindi
+ "hr", // Croatian
+ "hu", // Hungarian
+ "hy", // Armenian
+ "ia", // Interlingua
+ "id", // Indonesian
+ "is", // Icelandic
+ "it", // Italian
+ "it-CH", // Italian (Switzerland)
+ "it-IT", // Italian (Italy)
+ "ja", // Japanese
+ "jw", // Javanese
+ "ka", // Georgian
+ "kk", // Kazakh
+ "km", // Cambodian
+ "kn", // Kannada
+ "ko", // Korean
+ "ku", // Kurdish
+ "ky", // Kyrgyz
+ "la", // Latin
+ "ln", // Lingala
+ "lo", // Laothian
+ "lt", // Lithuanian
+ "lv", // Latvian
+ "mk", // Macedonian
+ "ml", // Malayalam
+ "mn", // Mongolian
+ "mo", // Moldavian
+ "mr", // Marathi
+ "ms", // Malay
+ "mt", // Maltese
+ "nb", // Norwegian (Bokmal)
+ "ne", // Nepali
+ "nl", // Dutch
+ "nn", // Norwegian (Nynorsk)
+ "no", // Norwegian
+ "oc", // Occitan
+ "or", // Oriya
+ "pa", // Punjabi
+ "pl", // Polish
+ "ps", // Pashto
+ "pt", // Portuguese
+ "pt-BR", // Portuguese (Brazil)
+ "pt-PT", // Portuguese (Portugal)
+ "qu", // Quechua
+ "rm", // Romansh
+ "ro", // Romanian
+ "ru", // Russian
+ "sd", // Sindhi
+ "sh", // Serbo-Croatian
+ "si", // Sinhalese
+ "sk", // Slovak
+ "sl", // Slovenian
+ "sn", // Shona
+ "so", // Somali
+ "sq", // Albanian
+ "sr", // Serbian
+ "st", // Sesotho
+ "su", // Sundanese
+ "sv", // Swedish
+ "sw", // Swahili
+ "ta", // Tamil
+ "te", // Telugu
+ "tg", // Tajik
+ "th", // Thai
+ "ti", // Tigrinya
+ "tk", // Turkmen
+ "to", // Tonga
+ "tr", // Turkish
+ "tt", // Tatar
+ "tw", // Twi
+ "ug", // Uighur
+ "uk", // Ukrainian
+ "ur", // Urdu
+ "uz", // Uzbek
+ "vi", // Vietnamese
+ "xh", // Xhosa
+ "yi", // Yiddish
+ "yo", // Yoruba
+ "zh", // Chinese
+ "zh-CN", // Chinese (Simplified)
+ "zh-TW", // Chinese (Traditional)
+ "zu", // Zulu
+};
+
+
// Get language and region from the OS.
void GetLanguageAndRegionFromOS(std::string* lang, std::string* region) {
// Later we may have to change this to be OS-dependent so that
@@ -742,6 +877,24 @@ const std::vector<std::string>& GetAvailableLocales() {
return locales;
}
+void GetAcceptLanguagesForLocale(const std::string& display_locale,
+ std::vector<std::string>* locale_codes) {
+ for (size_t i = 0; i < arraysize(kAcceptLanguageList); ++i) {
+ string16 display_name =
+ l10n_util::GetDisplayNameForLocale(kAcceptLanguageList[i],
+ display_locale, false);
+ // This is a hack. If ICU doesn't have a translated name for
+ // this language, GetDisplayNameForLocale will just return the
+ // language code. In that case, we skip it.
+ // TODO(jungshik) : Put them at the of the list with language codes
+ // enclosed by brackets.
+ if (IsStringASCII(display_name) &&
+ UTF16ToASCII(display_name) == kAcceptLanguageList[i])
+ continue;
+ locale_codes->push_back(kAcceptLanguageList[i]);
+ }
+}
+
BiDiLineIterator::~BiDiLineIterator() {
if (bidi_) {
ubidi_close(bidi_);
diff --git a/app/l10n_util.h b/app/l10n_util.h
index 37a40cd..eacb329 100644
--- a/app/l10n_util.h
+++ b/app/l10n_util.h
@@ -402,6 +402,10 @@ void SortStrings(const std::string& locale,
// en-US, es, fr, fi, pt-PT, pt-BR, etc.
const std::vector<std::string>& GetAvailableLocales();
+// Returns a vector of locale codes usable for accept-languages.
+void GetAcceptLanguagesForLocale(const std::string& display_locale,
+ std::vector<std::string>* locale_codes);
+
// A simple wrapper class for the bidirectional iterator of ICU.
// This class uses the bidirectional iterator of ICU to split a line of
// bidirectional texts into visual runs in its display order.
diff --git a/chrome/browser/gtk/options/fonts_languages_window_gtk.cc b/chrome/browser/gtk/options/fonts_languages_window_gtk.cc
index ef3a7cf..af0242e 100644
--- a/chrome/browser/gtk/options/fonts_languages_window_gtk.cc
+++ b/chrome/browser/gtk/options/fonts_languages_window_gtk.cc
@@ -10,6 +10,7 @@
#include "base/message_loop.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/gtk/options/fonts_page_gtk.h"
+#include "chrome/browser/gtk/options/languages_page_gtk.h"
#include "chrome/common/gtk_util.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
@@ -43,6 +44,9 @@ class FontsLanguagesWindowGtk {
// The fonts page.
FontsPageGtk fonts_page_;
+ // The languages page.
+ LanguagesPageGtk languages_page_;
+
DISALLOW_COPY_AND_ASSIGN(FontsLanguagesWindowGtk);
};
@@ -56,7 +60,8 @@ FontsLanguagesWindowGtk::FontsLanguagesWindowGtk(Profile* profile)
// the record comes from the original profile, but we explicitly use
// the original profile to avoid potential problems.
: profile_(profile->GetOriginalProfile()),
- fonts_page_(profile_) {
+ fonts_page_(profile_),
+ languages_page_(profile_) {
dialog_ = gtk_dialog_new_with_buttons(
l10n_util::GetStringFUTF8(IDS_FONT_LANGUAGE_SETTING_WINDOWS_TITLE,
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)).c_str(),
@@ -87,7 +92,7 @@ FontsLanguagesWindowGtk::FontsLanguagesWindowGtk(Profile* profile)
// Langauges tab.
gtk_notebook_append_page(
GTK_NOTEBOOK(notebook_),
- gtk_label_new("TODO content"),
+ languages_page_.get_page_widget(),
gtk_label_new(
l10n_util::GetStringUTF8(
IDS_FONT_LANGUAGE_SETTING_LANGUAGES_TAB_TITLE).c_str()));
diff --git a/chrome/browser/gtk/options/languages_page_gtk.cc b/chrome/browser/gtk/options/languages_page_gtk.cc
new file mode 100644
index 0000000..cfa466b
--- /dev/null
+++ b/chrome/browser/gtk/options/languages_page_gtk.cc
@@ -0,0 +1,342 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/gtk/options/languages_page_gtk.h"
+
+#include <set>
+#include <string>
+
+#include "app/l10n_util.h"
+#include "base/message_loop.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/language_combobox_model.h"
+#include "chrome/browser/language_order_table_model.h"
+#include "chrome/common/gtk_util.h"
+#include "chrome/common/pref_names.h"
+#include "grit/generated_resources.h"
+
+namespace {
+
+const int kWrapWidth = 475;
+
+GtkWidget* NewComboboxFromModel(ComboboxModel* model) {
+ GtkWidget* combobox = gtk_combo_box_new_text();
+ int count = model->GetItemCount();
+ for (int i = 0; i < count; ++i)
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combobox),
+ WideToUTF8(model->GetItemAt(i)).c_str());
+ return combobox;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AddLanguageDialog
+
+class AddLanguageDialog {
+ public:
+ AddLanguageDialog(Profile* profile, LanguagesPageGtk* delegate);
+ private:
+ // Callback for dialog buttons.
+ static void OnResponse(GtkDialog* dialog, int response_id,
+ AddLanguageDialog* window);
+
+ // Callback for window destruction.
+ static void OnWindowDestroy(GtkWidget* widget, AddLanguageDialog* window);
+
+ // The dialog window.
+ GtkWidget* dialog_;
+
+ // The language chooser combobox.
+ GtkWidget* combobox_;
+ scoped_ptr<LanguageComboboxModel> accept_language_combobox_model_;
+
+ // Used for call back to LanguagePageGtk that language has been selected.
+ LanguagesPageGtk* language_delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddLanguageDialog);
+};
+
+AddLanguageDialog::AddLanguageDialog(Profile* profile,
+ LanguagesPageGtk* delegate)
+ : language_delegate_(delegate) {
+ GtkWindow* parent = GTK_WINDOW(
+ gtk_widget_get_toplevel(delegate->get_page_widget()));
+
+ dialog_ = gtk_dialog_new_with_buttons(
+ l10n_util::GetStringUTF8(
+ IDS_FONT_LANGUAGE_SETTING_LANGUAGES_TAB_TITLE).c_str(),
+ parent,
+ static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_ADD,
+ GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_OK);
+ gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox),
+ gtk_util::kContentAreaSpacing);
+
+ const std::string app_locale = g_browser_process->GetApplicationLocale();
+ std::vector<std::string> locale_codes;
+ l10n_util::GetAcceptLanguagesForLocale(app_locale, &locale_codes);
+ accept_language_combobox_model_.reset(
+ new LanguageComboboxModel(profile, locale_codes));
+ combobox_ = NewComboboxFromModel(accept_language_combobox_model_.get());
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combobox_), 0);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), combobox_);
+
+ g_signal_connect(dialog_, "response", G_CALLBACK(OnResponse), this);
+ g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this);
+
+ gtk_widget_show_all(dialog_);
+}
+
+// static
+void AddLanguageDialog::OnResponse(GtkDialog* dialog,
+ int response_id,
+ AddLanguageDialog* window) {
+ if (response_id == GTK_RESPONSE_OK) {
+ int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(window->combobox_));
+ window->language_delegate_->OnAddLanguage(
+ window->accept_language_combobox_model_->GetLocaleFromIndex(selected));
+ }
+ gtk_widget_destroy(window->dialog_);
+}
+
+// static
+void AddLanguageDialog::OnWindowDestroy(GtkWidget* widget,
+ AddLanguageDialog* window) {
+ MessageLoop::current()->DeleteSoon(FROM_HERE, window);
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// LanguagesPageGtk
+
+LanguagesPageGtk::LanguagesPageGtk(Profile* profile)
+ : OptionsPageBase(profile), initializing_(true) {
+ Init();
+}
+
+LanguagesPageGtk::~LanguagesPageGtk() {
+}
+
+void LanguagesPageGtk::Init() {
+ page_ = gtk_vbox_new(FALSE, gtk_util::kContentAreaSpacing);
+ gtk_container_set_border_width(GTK_CONTAINER(page_),
+ gtk_util::kContentAreaBorder);
+
+ // Languages order controls.
+ GtkWidget* languages_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
+ gtk_box_pack_start(GTK_BOX(page_), languages_vbox,
+ TRUE, TRUE, 0);
+
+ GtkWidget* languages_instructions_label = gtk_label_new(
+ l10n_util::GetStringUTF8(
+ IDS_FONT_LANGUAGE_SETTING_LANGUAGES_INSTRUCTIONS).c_str());
+ gtk_misc_set_alignment(GTK_MISC(languages_instructions_label), 0, .5);
+ gtk_label_set_line_wrap(GTK_LABEL(languages_instructions_label), TRUE);
+ gtk_widget_set_size_request(languages_instructions_label, kWrapWidth, -1);
+ gtk_box_pack_start(GTK_BOX(languages_vbox), languages_instructions_label,
+ FALSE, FALSE, 0);
+
+ GtkWidget* languages_list_hbox = gtk_hbox_new(FALSE,
+ gtk_util::kControlSpacing);
+ gtk_box_pack_start(GTK_BOX(languages_vbox), languages_list_hbox,
+ TRUE, TRUE, 0);
+
+ // Languages order tree.
+ language_order_store_ = gtk_list_store_new(COL_COUNT,
+ G_TYPE_STRING);
+ language_order_tree_ = gtk_tree_view_new_with_model(
+ GTK_TREE_MODEL(language_order_store_));
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(language_order_tree_), FALSE);
+ GtkTreeViewColumn* lang_column = gtk_tree_view_column_new_with_attributes(
+ "",
+ gtk_cell_renderer_text_new(),
+ "text", COL_LANG,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(language_order_tree_), lang_column);
+ language_order_selection_ = gtk_tree_view_get_selection(
+ GTK_TREE_VIEW(language_order_tree_));
+ gtk_tree_selection_set_mode(language_order_selection_,
+ GTK_SELECTION_MULTIPLE);
+ g_signal_connect(G_OBJECT(language_order_selection_), "changed",
+ G_CALLBACK(OnSelectionChanged), this);
+ GtkWidget* scroll_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll_window),
+ GTK_SHADOW_ETCHED_IN);
+ gtk_container_add(GTK_CONTAINER(scroll_window), language_order_tree_);
+ gtk_box_pack_start(GTK_BOX(languages_list_hbox), scroll_window,
+ TRUE, TRUE, 0);
+
+ language_order_table_model_.reset(new LanguageOrderTableModel);
+ language_order_table_adapter_.reset(
+ new gtk_tree::ModelAdapter(this, language_order_store_,
+ language_order_table_model_.get()));
+
+ // Languages order buttons.
+ GtkWidget* languages_buttons_vbox = gtk_vbox_new(FALSE,
+ gtk_util::kControlSpacing);
+ gtk_box_pack_start(GTK_BOX(languages_list_hbox), languages_buttons_vbox,
+ FALSE, FALSE, 0);
+
+ add_button_ = gtk_button_new_with_label(l10n_util::GetStringUTF8(
+ IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_ADD_BUTTON_LABEL).c_str());
+ g_signal_connect(G_OBJECT(add_button_), "clicked",
+ G_CALLBACK(OnAddButtonClicked), this);
+ gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), add_button_,
+ FALSE, FALSE, 0);
+
+ std::string remove_button_text = l10n_util::GetStringUTF8(
+ IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_REMOVE_BUTTON_LABEL);
+ remove_button_ = gtk_button_new_with_label(remove_button_text.c_str());
+ g_signal_connect(G_OBJECT(remove_button_), "clicked",
+ G_CALLBACK(OnRemoveButtonClicked), this);
+ gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), remove_button_,
+ FALSE, FALSE, 0);
+
+ std::string move_up_button_text = l10n_util::GetStringUTF8(
+ IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_MOVEUP_BUTTON_LABEL);
+ move_up_button_ = gtk_button_new_with_label(move_up_button_text.c_str());
+ g_signal_connect(G_OBJECT(move_up_button_), "clicked",
+ G_CALLBACK(OnMoveUpButtonClicked), this);
+ gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), move_up_button_,
+ FALSE, FALSE, 0);
+
+ std::string move_down_button_text = l10n_util::GetStringUTF8(
+ IDS_FONT_LANGUAGE_SETTING_LANGUAGES_SELECTOR_MOVEDOWN_BUTTON_LABEL);
+ move_down_button_ = gtk_button_new_with_label(move_down_button_text.c_str());
+ g_signal_connect(G_OBJECT(move_down_button_), "clicked",
+ G_CALLBACK(OnMoveDownButtonClicked), this);
+ gtk_box_pack_start(GTK_BOX(languages_buttons_vbox), move_down_button_,
+ FALSE, FALSE, 0);
+
+ GtkWidget* spellchecker_vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
+ gtk_box_pack_start(GTK_BOX(page_), spellchecker_vbox,
+ FALSE, FALSE, 0);
+
+ // TODO(mattm): Spell checker controls.
+
+ // Initialize.
+ accept_languages_.Init(prefs::kAcceptLanguages,
+ profile()->GetPrefs(), this);
+ dictionary_language_.Init(prefs::kSpellCheckDictionary,
+ profile()->GetPrefs(), this);
+ enable_spellcheck_.Init(prefs::kEnableSpellCheck,
+ profile()->GetPrefs(), this);
+ enable_autospellcorrect_.Init(prefs::kEnableAutoSpellCorrect,
+ profile()->GetPrefs(), this);
+ NotifyPrefChanged(NULL);
+ EnableControls();
+}
+
+void LanguagesPageGtk::SetColumnValues(int row, GtkTreeIter* iter) {
+ std::wstring lang = language_order_table_model_->GetText(row, 0);
+ gtk_list_store_set(language_order_store_, iter,
+ COL_LANG, WideToUTF8(lang).c_str(),
+ -1);
+}
+
+void LanguagesPageGtk::OnAnyModelUpdate() {
+ if (!initializing_) {
+ accept_languages_.SetValue(ASCIIToWide(
+ language_order_table_model_->GetLanguageList()));
+ }
+ EnableControls();
+}
+
+void LanguagesPageGtk::EnableControls() {
+ int num_selected = gtk_tree_selection_count_selected_rows(
+ language_order_selection_);
+ int row_count = gtk_tree_model_iter_n_children(
+ GTK_TREE_MODEL(language_order_store_), NULL);
+ gtk_widget_set_sensitive(move_up_button_,
+ num_selected == 1 && FirstSelectedRowNum() > 0);
+ gtk_widget_set_sensitive(move_down_button_,
+ num_selected == 1 &&
+ FirstSelectedRowNum() < row_count - 1);
+ gtk_widget_set_sensitive(remove_button_, num_selected > 0);
+}
+
+int LanguagesPageGtk::FirstSelectedRowNum() {
+ int row_num = -1;
+ GList* list = gtk_tree_selection_get_selected_rows(language_order_selection_,
+ NULL);
+ if (list) {
+ row_num = gtk_tree::GetRowNumForPath(static_cast<GtkTreePath*>(list->data));
+ g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
+ g_list_free(list);
+ }
+ return row_num;
+}
+
+void LanguagesPageGtk::NotifyPrefChanged(const std::wstring* pref_name) {
+ initializing_ = true;
+ if (!pref_name || *pref_name == prefs::kAcceptLanguages) {
+ language_order_table_model_->SetAcceptLanguagesString(
+ WideToASCII(accept_languages_.GetValue()));
+ }
+ // TODO(mattm): Spell checker prefs.
+ initializing_ = false;
+}
+
+void LanguagesPageGtk::OnAddLanguage(const std::string& new_language) {
+ if (language_order_table_model_->Add(new_language))
+ gtk_tree::SelectAndFocusRowNum(language_order_table_model_->RowCount() - 1,
+ GTK_TREE_VIEW(language_order_tree_));
+}
+
+// static
+void LanguagesPageGtk::OnSelectionChanged(GtkTreeSelection *selection,
+ LanguagesPageGtk* languages_page) {
+ languages_page->EnableControls();
+}
+
+// static
+void LanguagesPageGtk::OnAddButtonClicked(GtkButton* button,
+ LanguagesPageGtk* languages_page) {
+ new AddLanguageDialog(languages_page->profile(), languages_page);
+}
+
+// static
+void LanguagesPageGtk::OnRemoveButtonClicked(GtkButton* button,
+ LanguagesPageGtk* languages_page) {
+ GList* list = gtk_tree_selection_get_selected_rows(
+ languages_page->language_order_selection_, NULL);
+ std::set<int> selected_rows;
+ GList* node;
+ for (node = list; node != NULL; node = node->next) {
+ selected_rows.insert(
+ gtk_tree::GetRowNumForPath(static_cast<GtkTreePath*>(node->data)));
+ }
+ g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
+ g_list_free(list);
+
+ for (std::set<int>::reverse_iterator selected = selected_rows.rbegin();
+ selected != selected_rows.rend(); ++selected) {
+ languages_page->language_order_table_model_->Remove(*selected);
+ }
+}
+
+// static
+void LanguagesPageGtk::OnMoveUpButtonClicked(GtkButton* button,
+ LanguagesPageGtk* languages_page) {
+ int item_selected = languages_page->FirstSelectedRowNum();
+ languages_page->language_order_table_model_->MoveUp(item_selected);
+ gtk_tree::SelectAndFocusRowNum(
+ item_selected - 1, GTK_TREE_VIEW(languages_page->language_order_tree_));
+}
+
+// static
+void LanguagesPageGtk::OnMoveDownButtonClicked(
+ GtkButton* button, LanguagesPageGtk* languages_page) {
+ int item_selected = languages_page->FirstSelectedRowNum();
+ languages_page->language_order_table_model_->MoveDown(item_selected);
+ gtk_tree::SelectAndFocusRowNum(
+ item_selected + 1, GTK_TREE_VIEW(languages_page->language_order_tree_));
+}
diff --git a/chrome/browser/gtk/options/languages_page_gtk.h b/chrome/browser/gtk/options/languages_page_gtk.h
new file mode 100644
index 0000000..a81161a
--- /dev/null
+++ b/chrome/browser/gtk/options/languages_page_gtk.h
@@ -0,0 +1,115 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The languages page of the Languages & languages options dialog, which
+// contains accept-languages and spellchecker language options.
+
+#ifndef CHROME_BROWSER_GTK_OPTIONS_LANGUAGES_PAGE_GTK_H_
+#define CHROME_BROWSER_GTK_OPTIONS_LANGUAGES_PAGE_GTK_H_
+
+#include <gtk/gtk.h>
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/options_page_base.h"
+#include "chrome/common/gtk_tree.h"
+#include "chrome/common/pref_member.h"
+#include "testing/gtest/include/gtest/gtest_prod.h"
+
+class LanguageOrderTableModel;
+
+class LanguagesPageGtk
+ : public OptionsPageBase,
+ public gtk_tree::ModelAdapter::Delegate {
+ public:
+ explicit LanguagesPageGtk(Profile* profile);
+ virtual ~LanguagesPageGtk();
+
+ GtkWidget* get_page_widget() const {
+ return page_;
+ }
+
+ // gtk_tree::ModelAdapter::Delegate implementation.
+ virtual void OnAnyModelUpdate();
+ virtual void SetColumnValues(int row, GtkTreeIter* iter);
+
+ // Callback from AddLanguageDialog.
+ void OnAddLanguage(const std::string& new_language);
+
+ private:
+ // Column ids for |language_order_store_|.
+ enum {
+ COL_LANG,
+ COL_COUNT,
+ };
+
+ void Init();
+
+ // Enable buttons based on selection state.
+ void EnableControls();
+
+ // Get the row number of the first selected row or -1 if no row is selected.
+ int FirstSelectedRowNum();
+
+ // Overridden from OptionsPageBase.
+ virtual void NotifyPrefChanged(const std::wstring* pref_name);
+
+ // Callbacks for accept languages widgets.
+ static void OnSelectionChanged(GtkTreeSelection *selection,
+ LanguagesPageGtk* languages_page);
+ static void OnAddButtonClicked(GtkButton* button,
+ LanguagesPageGtk* languages_page);
+ static void OnRemoveButtonClicked(GtkButton* button,
+ LanguagesPageGtk* languages_page);
+ static void OnMoveUpButtonClicked(GtkButton* button,
+ LanguagesPageGtk* languages_page);
+ static void OnMoveDownButtonClicked(GtkButton* button,
+ LanguagesPageGtk* languages_page);
+
+ // The accept languages widgets.
+ GtkListStore* language_order_store_;
+ GtkWidget* language_order_tree_;
+ GtkTreeSelection* language_order_selection_;
+ GtkWidget* move_up_button_;
+ GtkWidget* move_down_button_;
+ GtkWidget* add_button_;
+ GtkWidget* remove_button_;
+
+ // The spell checking widgets.
+ GtkWidget* dictionary_language_combobox_;
+ GtkWidget* enable_autospellcorrect_checkbox_;
+ GtkWidget* enable_spellchecking_checkbox_;
+
+ // The widget containing the options for this page.
+ GtkWidget* page_;
+
+ // The model for |language_order_store_|.
+ scoped_ptr<LanguageOrderTableModel> language_order_table_model_;
+ scoped_ptr<gtk_tree::ModelAdapter> language_order_table_adapter_;
+
+ // Accept languages pref.
+ StringPrefMember accept_languages_;
+
+ // The spellchecker "dictionary language" pref.
+ StringPrefMember dictionary_language_;
+
+ // SpellChecker enable pref.
+ BooleanPrefMember enable_spellcheck_;
+
+ // Auto spell correction pref.
+ BooleanPrefMember enable_autospellcorrect_;
+
+ // Flag to ignore gtk callbacks while we are loading prefs, to avoid
+ // then turning around and saving them again.
+ bool initializing_;
+
+ friend class LanguagesPageGtkTest;
+ FRIEND_TEST(LanguagesPageGtkTest, RemoveAcceptLang);
+ FRIEND_TEST(LanguagesPageGtkTest, RemoveMultipleAcceptLang);
+ FRIEND_TEST(LanguagesPageGtkTest, MoveAcceptLang);
+ FRIEND_TEST(LanguagesPageGtkTest, AddAcceptLang);
+
+ DISALLOW_COPY_AND_ASSIGN(LanguagesPageGtk);
+};
+
+#endif // CHROME_BROWSER_GTK_OPTIONS_LANGUAGES_PAGE_GTK_H_
diff --git a/chrome/browser/gtk/options/languages_page_gtk_unittest.cc b/chrome/browser/gtk/options/languages_page_gtk_unittest.cc
new file mode 100644
index 0000000..1ce49a5
--- /dev/null
+++ b/chrome/browser/gtk/options/languages_page_gtk_unittest.cc
@@ -0,0 +1,226 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/gtk/options/languages_page_gtk.h"
+
+#include <gtk/gtk.h>
+
+#include "base/string_util.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/testing_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class LanguagesPageGtkTest : public testing::Test {
+ public:
+ virtual void SetUp() {
+ profile_.reset(new TestingProfile());
+ }
+
+ // Get the accept languages displayed in the dialog in the order they are
+ // displayed, as a comma seperated string.
+ // Ex: EXPECT_STREQ("en,ja", GetDisplayedLangs(page).c_str());
+ std::string GetDisplayedLangs(const LanguagesPageGtk& page) {
+ std::vector<std::string> parts;
+ GtkTreeModel* tree_model = GTK_TREE_MODEL(page.language_order_store_);
+ GtkTreeIter iter;
+ if (!gtk_tree_model_get_iter_first(tree_model, &iter))
+ return std::string();
+ while (true) {
+ gchar* name;
+ gtk_tree_model_get(tree_model, &iter, LanguagesPageGtk::COL_LANG, &name,
+ -1);
+ parts.push_back(name);
+ g_free(name);
+ if (!gtk_tree_model_iter_next(tree_model, &iter))
+ break;
+ }
+ return JoinString(parts, ',');
+ }
+
+ protected:
+ MessageLoopForUI message_loop_;
+ scoped_ptr<TestingProfile> profile_;
+};
+
+TEST_F(LanguagesPageGtkTest, RemoveAcceptLang) {
+ //profile_->GetPrefs()->SetString(prefs::kAcceptLanguages, L"en,ja,es,fr,it");
+ profile_->GetPrefs()->SetString(prefs::kAcceptLanguages, L"en,ja,es");
+ LanguagesPageGtk page(profile_.get());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ GtkTreeIter iter;
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 1);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ gtk_button_clicked(GTK_BUTTON(page.remove_button_));
+ EXPECT_STREQ("English,Spanish", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("en,es", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 1);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ gtk_button_clicked(GTK_BUTTON(page.remove_button_));
+ EXPECT_STREQ("English", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("en", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 0);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ gtk_button_clicked(GTK_BUTTON(page.remove_button_));
+ EXPECT_STREQ("", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+}
+
+TEST_F(LanguagesPageGtkTest, RemoveMultipleAcceptLang) {
+ profile_->GetPrefs()->SetString(prefs::kAcceptLanguages, L"en,ja,es,fr,it");
+ LanguagesPageGtk page(profile_.get());
+ GtkTreeIter iter;
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 1);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 3);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 4);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ gtk_button_clicked(GTK_BUTTON(page.remove_button_));
+ EXPECT_STREQ("English,Spanish", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("en,es", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 1);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 0);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ gtk_button_clicked(GTK_BUTTON(page.remove_button_));
+ EXPECT_STREQ("", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+}
+
+TEST_F(LanguagesPageGtkTest, MoveAcceptLang) {
+ profile_->GetPrefs()->SetString(prefs::kAcceptLanguages, L"en,ja,es");
+ LanguagesPageGtk page(profile_.get());
+ EXPECT_STREQ("English,Japanese,Spanish", GetDisplayedLangs(page).c_str());
+ GtkTreeIter iter;
+
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(page.language_order_store_),
+ &iter, NULL, 0);
+ gtk_tree_selection_select_iter(page.language_order_selection_, &iter);
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+
+ gtk_button_clicked(GTK_BUTTON(page.move_down_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_STREQ("Japanese,English,Spanish", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("ja,en,es", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+
+ gtk_button_clicked(GTK_BUTTON(page.move_down_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_STREQ("Japanese,Spanish,English", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("ja,es,en", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+
+ gtk_button_clicked(GTK_BUTTON(page.move_up_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_STREQ("Japanese,English,Spanish", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("ja,en,es", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+
+ gtk_button_clicked(GTK_BUTTON(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_STREQ("English,Japanese,Spanish", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("en,ja,es", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+}
+
+TEST_F(LanguagesPageGtkTest, AddAcceptLang) {
+ profile_->GetPrefs()->SetString(prefs::kAcceptLanguages, L"");
+ LanguagesPageGtk page(profile_.get());
+ EXPECT_STREQ("", GetDisplayedLangs(page).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+
+ page.OnAddLanguage("en");
+ EXPECT_STREQ("English", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("en", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+ EXPECT_EQ(0, page.FirstSelectedRowNum());
+
+ page.OnAddLanguage("es");
+ EXPECT_STREQ("English,Spanish", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("en,es", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+ EXPECT_EQ(1, page.FirstSelectedRowNum());
+
+ // Duplicates should be ignored and selection should not be changed.
+ gtk_tree_selection_unselect_all(page.language_order_selection_);
+ page.OnAddLanguage("en");
+ EXPECT_STREQ("English,Spanish", GetDisplayedLangs(page).c_str());
+ EXPECT_STREQ("en,es", WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)).c_str());
+ EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(page.add_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_up_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.move_down_button_));
+ EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(page.remove_button_));
+ EXPECT_EQ(0, gtk_tree_selection_count_selected_rows(
+ page.language_order_selection_));
+}
diff --git a/chrome/browser/language_order_table_model.cc b/chrome/browser/language_order_table_model.cc
index 50799d2..e5bd403e 100644
--- a/chrome/browser/language_order_table_model.cc
+++ b/chrome/browser/language_order_table_model.cc
@@ -32,17 +32,18 @@ std::wstring LanguageOrderTableModel::GetText(int row, int column_id) {
true));
}
-void LanguageOrderTableModel::Add(const std::string& language) {
+bool LanguageOrderTableModel::Add(const std::string& language) {
if (language.empty())
- return;
+ return false;
// Check for selecting duplicated language.
for (std::vector<std::string>::const_iterator cit = languages_.begin();
cit != languages_.end(); ++cit)
if (*cit == language)
- return;
+ return false;
languages_.push_back(language);
if (observer_)
observer_->OnItemsAdded(RowCount() - 1, 1);
+ return true;
}
void LanguageOrderTableModel::Remove(int index) {
diff --git a/chrome/browser/language_order_table_model.h b/chrome/browser/language_order_table_model.h
index 327fe67..911d55e 100644
--- a/chrome/browser/language_order_table_model.h
+++ b/chrome/browser/language_order_table_model.h
@@ -18,8 +18,8 @@ class LanguageOrderTableModel : public TableModel {
// Set Language List.
void SetAcceptLanguagesString(const std::string& language_list);
- // Add at the end.
- void Add(const std::string& language);
+ // Add at the end. Return true if the language was added.
+ bool Add(const std::string& language);
// Removes the entry at the specified index.
void Remove(int index);
diff --git a/chrome/browser/views/options/languages_page_view.cc b/chrome/browser/views/options/languages_page_view.cc
index abb2490..2fdc786 100644
--- a/chrome/browser/views/options/languages_page_view.cc
+++ b/chrome/browser/views/options/languages_page_view.cc
@@ -39,140 +39,6 @@
#include "views/widget/widget.h"
#include "views/window/window.h"
-static const char* const accept_language_list[] = {
- "af", // Afrikaans
- "am", // Amharic
- "ar", // Arabic
- "az", // Azerbaijani
- "be", // Belarusian
- "bg", // Bulgarian
- "bh", // Bihari
- "bn", // Bengali
- "br", // Breton
- "bs", // Bosnian
- "ca", // Catalan
- "co", // Corsican
- "cs", // Czech
- "cy", // Welsh
- "da", // Danish
- "de", // German
- "de-AT", // German (Austria)
- "de-CH", // German (Switzerland)
- "de-DE", // German (Germany)
- "el", // Greek
- "en", // English
- "en-AU", // English (Austrailia)
- "en-CA", // English (Canada)
- "en-GB", // English (UK)
- "en-NZ", // English (New Zealand)
- "en-US", // English (US)
- "en-ZA", // English (South Africa)
- "eo", // Esperanto
- // TODO(jungshik) : Do we want to list all es-Foo for Latin-American
- // Spanish speaking countries?
- "es", // Spanish
- "et", // Estonian
- "eu", // Basque
- "fa", // Persian
- "fi", // Finnish
- "fil", // Filipino
- "fo", // Faroese
- "fr", // French
- "fr-CA", // French (Canada)
- "fr-CH", // French (Switzerland)
- "fr-FR", // French (France)
- "fy", // Frisian
- "ga", // Irish
- "gd", // Scots Gaelic
- "gl", // Galician
- "gn", // Guarani
- "gu", // Gujarati
- "he", // Hebrew
- "hi", // Hindi
- "hr", // Croatian
- "hu", // Hungarian
- "hy", // Armenian
- "ia", // Interlingua
- "id", // Indonesian
- "is", // Icelandic
- "it", // Italian
- "it-CH", // Italian (Switzerland)
- "it-IT", // Italian (Italy)
- "ja", // Japanese
- "jw", // Javanese
- "ka", // Georgian
- "kk", // Kazakh
- "km", // Cambodian
- "kn", // Kannada
- "ko", // Korean
- "ku", // Kurdish
- "ky", // Kyrgyz
- "la", // Latin
- "ln", // Lingala
- "lo", // Laothian
- "lt", // Lithuanian
- "lv", // Latvian
- "mk", // Macedonian
- "ml", // Malayalam
- "mn", // Mongolian
- "mo", // Moldavian
- "mr", // Marathi
- "ms", // Malay
- "mt", // Maltese
- "nb", // Norwegian (Bokmal)
- "ne", // Nepali
- "nl", // Dutch
- "nn", // Norwegian (Nynorsk)
- "no", // Norwegian
- "oc", // Occitan
- "or", // Oriya
- "pa", // Punjabi
- "pl", // Polish
- "ps", // Pashto
- "pt", // Portuguese
- "pt-BR", // Portuguese (Brazil)
- "pt-PT", // Portuguese (Portugal)
- "qu", // Quechua
- "rm", // Romansh
- "ro", // Romanian
- "ru", // Russian
- "sd", // Sindhi
- "sh", // Serbo-Croatian
- "si", // Sinhalese
- "sk", // Slovak
- "sl", // Slovenian
- "sn", // Shona
- "so", // Somali
- "sq", // Albanian
- "sr", // Serbian
- "st", // Sesotho
- "su", // Sundanese
- "sv", // Swedish
- "sw", // Swahili
- "ta", // Tamil
- "te", // Telugu
- "tg", // Tajik
- "th", // Thai
- "ti", // Tigrinya
- "tk", // Turkmen
- "to", // Tonga
- "tr", // Turkish
- "tt", // Tatar
- "tw", // Twi
- "ug", // Uighur
- "uk", // Ukrainian
- "ur", // Urdu
- "uz", // Uzbek
- "vi", // Vietnamese
- "xh", // Xhosa
- "yi", // Yiddish
- "yo", // Yoruba
- "zh", // Chinese
- "zh-CN", // Chinese (Simplified)
- "zh-TW", // Chinese (Traditional)
- "zu", // Zulu
-};
-
///////////////////////////////////////////////////////////////////////////////
// AddLanguageWindowView
//
@@ -289,22 +155,10 @@ void AddLanguageWindowView::ViewHierarchyChanged(bool is_add,
void AddLanguageWindowView::Init() {
// Determine Locale Codes.
- std::vector<std::string> locale_codes;
const std::string app_locale = g_browser_process->GetApplicationLocale();
- for (size_t i = 0; i < arraysize(accept_language_list); ++i) {
- string16 display_name =
- l10n_util::GetDisplayNameForLocale(accept_language_list[i],
- app_locale, false);
- // This is a hack. If ICU doesn't have a translated name for
- // this language, GetDisplayNameForLocale will just return the
- // language code. In that case, we skip it.
- // TODO(jungshik) : Put them at the of the list with language codes
- // enclosed by brackets.
- if (IsStringASCII(display_name) &&
- UTF16ToASCII(display_name) == accept_language_list[i])
- continue;
- locale_codes.push_back(accept_language_list[i]);
- }
+ std::vector<std::string> locale_codes;
+ l10n_util::GetAcceptLanguagesForLocale(app_locale, &locale_codes);
+
accept_language_combobox_model_.reset(new LanguageComboboxModel(
profile_, locale_codes));
accept_language_combobox_ = new views::Combobox(
@@ -375,9 +229,10 @@ void LanguagesPageView::ButtonPressed(views::Button* sender) {
}
void LanguagesPageView::OnAddLanguage(const std::string& new_language) {
- language_order_table_model_->Add(new_language);
- language_order_table_->Select(language_order_table_model_->RowCount() - 1);
- OnSelectionChanged();
+ if (language_order_table_model_->Add(new_language)) {
+ language_order_table_->Select(language_order_table_model_->RowCount() - 1);
+ OnSelectionChanged();
+ }
}
void LanguagesPageView::InitControlLayout() {
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index a28eb1d..69700e7 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1226,6 +1226,8 @@
'browser/gtk/options/fonts_page_gtk.h',
'browser/gtk/options/general_page_gtk.cc',
'browser/gtk/options/general_page_gtk.h',
+ 'browser/gtk/options/languages_page_gtk.cc',
+ 'browser/gtk/options/languages_page_gtk.h',
'browser/gtk/options/options_layout_gtk.cc',
'browser/gtk/options/options_layout_gtk.h',
'browser/gtk/options/options_window_gtk.cc',
@@ -3877,6 +3879,7 @@
'browser/gtk/bookmark_editor_gtk_unittest.cc',
'browser/gtk/go_button_gtk_unittest.cc',
'browser/gtk/options/cookies_view_unittest.cc',
+ 'browser/gtk/options/languages_page_gtk_unittest.cc',
'browser/gtk/tabs/tab_renderer_gtk_unittest.cc',
'browser/gtk/view_id_util_unittest.cc',
'browser/history/expire_history_backend_unittest.cc',
diff --git a/chrome/test/data/valgrind/unit_tests.gtest_linux.txt b/chrome/test/data/valgrind/unit_tests.gtest_linux.txt
index 58220ef..f52ecf8 100644
--- a/chrome/test/data/valgrind/unit_tests.gtest_linux.txt
+++ b/chrome/test/data/valgrind/unit_tests.gtest_linux.txt
@@ -2,3 +2,4 @@
# Only fails on the bots?
BookmarkEditorGtkTest.*
CookiesViewTest.*
+LanguagesPageGtkTest.*