diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 04:48:24 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 04:48:24 +0000 |
commit | 65705eaa06155250c255ecdb766ebfeb081025f7 (patch) | |
tree | c49d0fc18479349f09643423c5b2f5862a0a33c6 /chrome/browser/gtk/options | |
parent | 1a6b30a619cba771cb9c4ed4da9c3778634567ad (diff) | |
download | chromium_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
Diffstat (limited to 'chrome/browser/gtk/options')
-rw-r--r-- | chrome/browser/gtk/options/fonts_languages_window_gtk.cc | 9 | ||||
-rw-r--r-- | chrome/browser/gtk/options/languages_page_gtk.cc | 342 | ||||
-rw-r--r-- | chrome/browser/gtk/options/languages_page_gtk.h | 115 | ||||
-rw-r--r-- | chrome/browser/gtk/options/languages_page_gtk_unittest.cc | 226 |
4 files changed, 690 insertions, 2 deletions
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_)); +} |