From 53222ef517b97249df1e1a6db2e29c0d86b2e773 Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Thu, 31 May 2012 02:56:42 +0200
Subject: [PATCH] STORM-276 Match preferences look to that of the auto-replace
 functionality in STORM-1738

---
 indra/newview/CMakeLists.txt                  |   2 +
 indra/newview/llfloaterpreference.cpp         | 131 +------------
 indra/newview/llfloaterpreference.h           |   3 +-
 indra/newview/llfloaterspellchecksettings.cpp | 179 ++++++++++++++++++
 indra/newview/llfloaterspellchecksettings.h   |  48 +++++
 indra/newview/llviewerfloaterreg.cpp          |   2 +
 .../default/xui/en/floater_preferences.xml    |   6 -
 .../default/xui/en/floater_spellcheck.xml     | 175 +++++++++++++++++
 .../default/xui/en/panel_preferences_chat.xml |  11 ++
 .../xui/en/panel_preferences_spellcheck.xml   | 136 -------------
 10 files changed, 424 insertions(+), 269 deletions(-)
 create mode 100644 indra/newview/llfloaterspellchecksettings.cpp
 create mode 100644 indra/newview/llfloaterspellchecksettings.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_spellcheck.xml
 delete mode 100644 indra/newview/skins/default/xui/en/panel_preferences_spellcheck.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 8a6c88222bf..b83f32c28ed 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -236,6 +236,7 @@ set(viewer_SOURCE_FILES
     llfloatersidepanelcontainer.cpp
     llfloatersnapshot.cpp
     llfloatersounddevices.cpp
+    llfloaterspellchecksettings.cpp
     llfloatertelehub.cpp
     llfloatertestinspectors.cpp
     llfloatertestlistview.cpp
@@ -792,6 +793,7 @@ set(viewer_HEADER_FILES
     llfloatersidepanelcontainer.h
     llfloatersnapshot.h
     llfloatersounddevices.h
+    llfloaterspellchecksettings.h
     llfloatertelehub.h
     llfloatertestinspectors.h
     llfloatertestlistview.h
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index c096537de69..ae9a4a9876c 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -66,7 +66,6 @@
 #include "llsky.h"
 #include "llscrolllistctrl.h"
 #include "llscrolllistitem.h"
-#include "llspellcheck.h"
 #include "llsliderctrl.h"
 #include "lltabcontainer.h"
 #include "lltrans.h"
@@ -111,8 +110,6 @@
 #include "lllogininstance.h"        // to check if logged in yet
 #include "llsdserialize.h"
 
-#include <boost/algorithm/string.hpp>
-
 const F32 MAX_USER_FAR_CLIP = 512.f;
 const F32 MIN_USER_FAR_CLIP = 64.f;
 const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;
@@ -349,6 +346,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.BlockList",				boost::bind(&LLFloaterPreference::onClickBlockList, this));
 	mCommitCallbackRegistrar.add("Pref.Proxy",					boost::bind(&LLFloaterPreference::onClickProxySettings, this));
 	mCommitCallbackRegistrar.add("Pref.TranslationSettings",	boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
+	mCommitCallbackRegistrar.add("Pref.SpellChecker",           boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
 	
 	sSkin = gSavedSettings.getString("SkinCurrent");
 
@@ -448,11 +446,6 @@ BOOL LLFloaterPreference::postBuild()
 
 	getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
 
-	gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&LLFloaterPreference::refreshDictLists, this, false));
-	getChild<LLUICtrl>("combo_spellcheck_dict")->setCommitCallback(boost::bind(&LLFloaterPreference::refreshDictLists, this, false));
-	getChild<LLUICtrl>("btn_spellcheck_moveleft")->setCommitCallback(boost::bind(&LLFloaterPreference::onClickDictMove, this, "list_spellcheck_active", "list_spellcheck_available"));
-	getChild<LLUICtrl>("btn_spellcheck_moveright")->setCommitCallback(boost::bind(&LLFloaterPreference::onClickDictMove, this, "list_spellcheck_available", "list_spellcheck_active"));
-
 	// if floater is opened before login set default localized busy message
 	if (LLStartUp::getStartupState() < STATE_STARTED)
 	{
@@ -585,24 +578,6 @@ void LLFloaterPreference::apply()
 		}
 	}
 
-	if (hasChild("check_spellcheck"), TRUE)
-	{
-		std::list<std::string> list_dict;
-
-		LLComboBox* dict_combo = findChild<LLComboBox>("combo_spellcheck_dict");
-		const std::string dict_name = dict_combo->getSelectedItemLabel();
-		if (!dict_name.empty())
-		{
-			list_dict.push_back(dict_name);
-
-			LLScrollListCtrl* list_ctrl = findChild<LLScrollListCtrl>("list_spellcheck_active");
-			std::vector<LLScrollListItem*> list_items = list_ctrl->getAllData();
-			for (std::vector<LLScrollListItem*>::const_iterator item_it = list_items.begin(); item_it != list_items.end(); ++item_it)
-				list_dict.push_back((*item_it)->getColumn(0)->getValue().asString());
-		}
-		gSavedSettings.setString("SpellCheckDictionary", boost::join(list_dict, ","));
-	}
-
 	saveAvatarProperties();
 
 	if (mClickActionDirty)
@@ -713,8 +688,6 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	// Load (double-)click to walk/teleport settings.
 	updateClickActionControls();
 	
-	refreshDictLists(true);
-
 	// Enabled/disabled popups, might have been changed by user actions
 	// while preferences floater was closed.
 	buildPopupLists();
@@ -894,25 +867,6 @@ void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue)
 	}
 }
 
-void LLFloaterPreference::onClickDictMove(const std::string& from, const std::string& to)
-{
-	LLScrollListCtrl* from_ctrl = findChild<LLScrollListCtrl>(from);
-	LLScrollListCtrl* to_ctrl = findChild<LLScrollListCtrl>(to);
-
-	LLSD row;
-	row["columns"][0]["column"] = "name";
-	row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL";
-	row["columns"][0]["font"]["style"] = "NORMAL";
-
-	std::vector<LLScrollListItem*> sel_items = from_ctrl->getAllSelected();
-	for (std::vector<LLScrollListItem*>::const_iterator sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it)
-	{
-		row["columns"][0]["value"] = (*sel_it)->getColumn(0)->getValue();
-		to_ctrl->addElement(row);
-	}
-	from_ctrl->deleteSelectedItems();
-}
-
 void LLFloaterPreference::onClickSetCache()
 {
 	std::string cur_name(gSavedSettings.getString("CacheLocation"));
@@ -978,84 +932,6 @@ void LLFloaterPreference::refreshSkin(void* data)
 	self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
 }
 
-void LLFloaterPreference::refreshDictLists(bool from_settings)
-{
-	bool enabled = gSavedSettings.getBOOL("SpellCheck");
-	getChild<LLUICtrl>("btn_spellcheck_moveleft")->setEnabled(enabled);
-	getChild<LLUICtrl>("btn_spellcheck_moveright")->setEnabled(enabled);
-
-	// Populate the dictionary combobox
-	LLComboBox* dict_combo = findChild<LLComboBox>("combo_spellcheck_dict");
-	std::string dict_cur = dict_combo->getSelectedItemLabel();
-	if ((dict_cur.empty() || from_settings) && (LLSpellChecker::getUseSpellCheck()))
-		dict_cur = LLSpellChecker::instance().getActiveDictionary();
-	dict_combo->clearRows();
-	dict_combo->setEnabled(enabled);
-
-	const LLSD& dict_map = LLSpellChecker::getDictionaryMap();
-	if (dict_map.size())
-	{
-		for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it)
-		{
-			const LLSD& dict = *dict_it;
-			if ( (dict["installed"].asBoolean()) && (dict["is_primary"].asBoolean()) && (dict.has("language")) )
-				dict_combo->add(dict["language"].asString());
-		}
-		if (!dict_combo->selectByValue(dict_cur))
-			dict_combo->clear();
-	}
-
-	// Populate the available and active dictionary list
-	LLScrollListCtrl* avail_ctrl = findChild<LLScrollListCtrl>("list_spellcheck_available");
-	LLScrollListCtrl* active_ctrl = findChild<LLScrollListCtrl>("list_spellcheck_active");
-
-	LLSpellChecker::dict_list_t active_list;
-	if ( ((!avail_ctrl->getItemCount()) && (!active_ctrl->getItemCount())) || (from_settings) )
-	{
-		if (LLSpellChecker::getUseSpellCheck())
-			active_list = LLSpellChecker::instance().getSecondaryDictionaries();
-	}
-	else
-	{
-		std::vector<LLScrollListItem*> active_items = active_ctrl->getAllData();
-		for (std::vector<LLScrollListItem*>::const_iterator item_it = active_items.begin(); item_it != active_items.end(); ++item_it)
-		{
-			std::string dict = (*item_it)->getColumn(0)->getValue().asString();
-			if (dict_cur != dict)
-				active_list.push_back(dict);
-		}
-	}
-
-	LLSD row;
-	row["columns"][0]["column"] = "name";
-	row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL";
-	row["columns"][0]["font"]["style"] = "NORMAL";
-
-	active_ctrl->clearRows();
-	active_ctrl->setEnabled(enabled);
-	active_ctrl->sortByColumnIndex(0, true);
-	for (LLSpellChecker::dict_list_t::const_iterator it = active_list.begin(); it != active_list.end(); ++it)
-	{
-		row["columns"][0]["value"] = *it;
-		active_ctrl->addElement(row);
-	}
-	active_list.push_back(dict_cur);
-
-	avail_ctrl->clearRows();
-	avail_ctrl->setEnabled(enabled);
-	avail_ctrl->sortByColumnIndex(0, true);
-	for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it)
-	{
-		const LLSD& dict = *dict_it;
-		if ( (dict["installed"].asBoolean()) && (dict.has("language")) && 
-			 (active_list.end() == std::find(active_list.begin(), active_list.end(), dict["language"].asString())) )
-		{
-			row["columns"][0]["value"] = dict["language"].asString();
-			avail_ctrl->addElement(row);
-		}
-	}
-}
-
 void LLFloaterPreference::buildPopupLists()
 {
 	LLScrollListCtrl& disabled_popups =
@@ -1639,6 +1515,11 @@ void LLFloaterPreference::onClickTranslationSettings()
 	LLFloaterReg::showInstance("prefs_translation");
 }
 
+void LLFloaterPreference::onClickSpellChecker()
+{
+	LLFloaterReg::showInstance("prefs_spellchecker");
+}
+
 void LLFloaterPreference::onClickActionChange()
 {
 	mClickActionDirty = true;
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index af10af7f48f..669099ad7b5 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -121,7 +121,6 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 
 	void setCacheLocation(const LLStringExplicit& location);
 
-	void onClickDictMove(const std::string& from, const std::string& to);
 	void onClickSetCache();
 	void onClickResetCache();
 	void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata);
@@ -158,11 +157,11 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	void onClickBlockList();
 	void onClickProxySettings();
 	void onClickTranslationSettings();
+	void onClickSpellChecker();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
 	
 	void buildPopupLists();
-	void refreshDictLists(bool from_settings);
 	static void refreshSkin(void* data);
 private:
 	static std::string sSkin;
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
new file mode 100644
index 00000000000..ff5afc8169e
--- /dev/null
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -0,0 +1,179 @@
+/** 
+ * @file llfloaterspellchecksettings.h
+ * @brief Spell checker settings floater
+ *
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llcombobox.h"
+#include "llfloaterspellchecksettings.h"
+#include "llscrolllistctrl.h"
+#include "llspellcheck.h"
+#include "llviewercontrol.h"
+
+#include <boost/algorithm/string.hpp>
+
+LLFloaterSpellCheckerSettings::LLFloaterSpellCheckerSettings(const LLSD& key)
+	: LLFloater(key)
+{
+}
+
+BOOL LLFloaterSpellCheckerSettings::postBuild(void)
+{
+	gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaryLists, this, false));
+	getChild<LLUICtrl>("spellcheck_main_combo")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaryLists, this, false));
+	getChild<LLUICtrl>("spellcheck_moveleft_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onClickDictMove, this, "spellcheck_active_list", "spellcheck_available_list"));
+	getChild<LLUICtrl>("spellcheck_moveright_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onClickDictMove, this, "spellcheck_available_list", "spellcheck_active_list"));
+	getChild<LLUICtrl>("spellcheck_ok")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onOK, this));
+	getChild<LLUICtrl>("spellcheck_cancel")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onCancel, this));
+
+	return true;
+}
+
+void LLFloaterSpellCheckerSettings::onCancel()
+{
+	closeFloater(false);
+}
+
+void LLFloaterSpellCheckerSettings::onClickDictMove(const std::string& from, const std::string& to)
+{
+	LLScrollListCtrl* from_ctrl = findChild<LLScrollListCtrl>(from);
+	LLScrollListCtrl* to_ctrl = findChild<LLScrollListCtrl>(to);
+
+	LLSD row;
+	row["columns"][0]["column"] = "name";
+	row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL";
+	row["columns"][0]["font"]["style"] = "NORMAL";
+
+	std::vector<LLScrollListItem*> sel_items = from_ctrl->getAllSelected();
+	for (std::vector<LLScrollListItem*>::const_iterator sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it)
+	{
+		row["columns"][0]["value"] = (*sel_it)->getColumn(0)->getValue();
+		to_ctrl->addElement(row);
+	}
+	from_ctrl->deleteSelectedItems();
+}
+
+void LLFloaterSpellCheckerSettings::onOK()
+{
+	std::list<std::string> list_dict;
+
+	LLComboBox* dict_combo = findChild<LLComboBox>("spellcheck_main_combo");
+	const std::string dict_name = dict_combo->getSelectedItemLabel();
+	if (!dict_name.empty())
+	{
+		list_dict.push_back(dict_name);
+
+		LLScrollListCtrl* list_ctrl = findChild<LLScrollListCtrl>("spellcheck_active_list");
+		std::vector<LLScrollListItem*> list_items = list_ctrl->getAllData();
+		for (std::vector<LLScrollListItem*>::const_iterator item_it = list_items.begin(); item_it != list_items.end(); ++item_it)
+			list_dict.push_back((*item_it)->getColumn(0)->getValue().asString());
+	}
+	gSavedSettings.setString("SpellCheckDictionary", boost::join(list_dict, ","));
+
+	closeFloater(false);
+}
+
+void LLFloaterSpellCheckerSettings::onOpen(const LLSD& key)
+{
+	refreshDictionaryLists(true);
+}
+
+void LLFloaterSpellCheckerSettings::refreshDictionaryLists(bool from_settings)
+{
+	bool enabled = gSavedSettings.getBOOL("SpellCheck");
+	getChild<LLUICtrl>("spellcheck_moveleft_btn")->setEnabled(enabled);
+	getChild<LLUICtrl>("spellcheck_moveright_btn")->setEnabled(enabled);
+
+	// Populate the dictionary combobox
+	LLComboBox* dict_combo = findChild<LLComboBox>("spellcheck_main_combo");
+	std::string dict_cur = dict_combo->getSelectedItemLabel();
+	if ((dict_cur.empty() || from_settings) && (LLSpellChecker::getUseSpellCheck()))
+		dict_cur = LLSpellChecker::instance().getActiveDictionary();
+	dict_combo->clearRows();
+	dict_combo->setEnabled(enabled);
+
+	const LLSD& dict_map = LLSpellChecker::getDictionaryMap();
+	if (dict_map.size())
+	{
+		for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it)
+		{
+			const LLSD& dict = *dict_it;
+			if ( (dict["installed"].asBoolean()) && (dict["is_primary"].asBoolean()) && (dict.has("language")) )
+				dict_combo->add(dict["language"].asString());
+		}
+		if (!dict_combo->selectByValue(dict_cur))
+			dict_combo->clear();
+	}
+
+	// Populate the available and active dictionary list
+	LLScrollListCtrl* avail_ctrl = findChild<LLScrollListCtrl>("spellcheck_available_list");
+	LLScrollListCtrl* active_ctrl = findChild<LLScrollListCtrl>("spellcheck_active_list");
+
+	LLSpellChecker::dict_list_t active_list;
+	if ( ((!avail_ctrl->getItemCount()) && (!active_ctrl->getItemCount())) || (from_settings) )
+	{
+		if (LLSpellChecker::getUseSpellCheck())
+			active_list = LLSpellChecker::instance().getSecondaryDictionaries();
+	}
+	else
+	{
+		std::vector<LLScrollListItem*> active_items = active_ctrl->getAllData();
+		for (std::vector<LLScrollListItem*>::const_iterator item_it = active_items.begin(); item_it != active_items.end(); ++item_it)
+		{
+			std::string dict = (*item_it)->getColumn(0)->getValue().asString();
+			if (dict_cur != dict)
+				active_list.push_back(dict);
+		}
+	}
+
+	LLSD row;
+	row["columns"][0]["column"] = "name";
+	row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL";
+	row["columns"][0]["font"]["style"] = "NORMAL";
+
+	active_ctrl->clearRows();
+	active_ctrl->setEnabled(enabled);
+	active_ctrl->sortByColumnIndex(0, true);
+	for (LLSpellChecker::dict_list_t::const_iterator it = active_list.begin(); it != active_list.end(); ++it)
+	{
+		row["columns"][0]["value"] = *it;
+		active_ctrl->addElement(row);
+	}
+	active_list.push_back(dict_cur);
+
+	avail_ctrl->clearRows();
+	avail_ctrl->setEnabled(enabled);
+	avail_ctrl->sortByColumnIndex(0, true);
+	for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it)
+	{
+		const LLSD& dict = *dict_it;
+		if ( (dict["installed"].asBoolean()) && (dict.has("language")) && 
+			 (active_list.end() == std::find(active_list.begin(), active_list.end(), dict["language"].asString())) )
+		{
+			row["columns"][0]["value"] = dict["language"].asString();
+			avail_ctrl->addElement(row);
+		}
+	}
+}
diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h
new file mode 100644
index 00000000000..33c376fff63
--- /dev/null
+++ b/indra/newview/llfloaterspellchecksettings.h
@@ -0,0 +1,48 @@
+/** 
+ * @file llfloaterspellchecksettings.h
+ * @brief Spell checker settings floater
+ *
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLFLOATERAUTOREPLACESETTINGS_H
+#define LLFLOATERAUTOREPLACESETTINGS_H
+
+#include "llfloater.h"
+
+class LLFloaterSpellCheckerSettings : public LLFloater
+{
+public:
+	LLFloaterSpellCheckerSettings(const LLSD& key);
+
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
+
+protected:
+	void onCancel();
+	void onClickDictMove(const std::string& from, const std::string& to);
+	void onOK();
+	void onSave();
+	void refreshDictionaryLists(bool from_settings);
+};
+
+#endif  // LLFLOATERAUTOREPLACESETTINGS_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 7fdaac68c87..e9ce04fd3f0 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -100,6 +100,7 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llfloatersnapshot.h"
 #include "llfloatersounddevices.h"
+#include "llfloaterspellchecksettings.h"
 #include "llfloatertelehub.h"
 #include "llfloatertestinspectors.h"
 #include "llfloatertestlistview.h"
@@ -248,6 +249,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
 	LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
 	LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>);
+	LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
 	LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
 	LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);
 	LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index 9433866c4d0..bd6faf4ed8f 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -120,12 +120,6 @@
          layout="topleft"
          help_topic="preferences_advanced1_tab"
          name="advanced1" />
-        <panel
-         class="panel_preference"
-         filename="panel_preferences_spellcheck.xml"
-         label="Spell Check"
-         layout="topleft"
-         name="spell_check" />
     </tab_container>
 
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_spellcheck.xml b/indra/newview/skins/default/xui/en/floater_spellcheck.xml
new file mode 100644
index 00000000000..bd3f60cf4a1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_spellcheck.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="true"
+ can_minimize="true"
+ bottom="275"
+ left="300"
+ can_resize="false"
+ height="330"
+ width="490"
+ name="spellcheck_floater"
+ title="Spell Checker Settings">
+  <check_box
+   bottom_delta="30"
+   control_name="SpellCheck"
+   left_delta="15"
+   height="16"
+   width="100"
+   follows="left|top"
+   label="Enable spell checker"
+   name="spellcheck_enable" />
+  <view_border
+   top_pad="10"
+   left="2"
+   height="0"
+   width="491"
+   follows="left|top"
+   bevel_style="none"
+   border_thickness="1"
+   mouse_opaque="false"
+   name="divisor1"/>
+  <text
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="10"
+   layout="topleft"
+   left="38"
+   mouse_opaque="false"
+   name="spellcheck_main"
+   top_pad="15"
+   type="string"
+   width="90"
+  >
+    Main dictionary :
+  </text>
+  <combo_box
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="23"
+   layout="topleft"
+   left_pad="10"
+   name="spellcheck_main_combo"
+   top_pad="-15"
+   width="175"
+  />
+  <text
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="10"
+   label="Logs:"
+   layout="topleft"
+   left="38"
+   mouse_opaque="false"
+   name="spellcheck_additional"
+   top_pad="15"
+   type="string"
+   width="190"
+  >
+    Additional dictionaries :
+  </text>
+  <text
+   follows="top|left"
+   height="12"
+   layout="topleft"
+   left="55"
+   length="1"
+   name="spellcheck_available"
+   top_pad="10"
+   type="string"
+   width="175">
+      Available
+  </text>
+  <text
+   follows="top|left"
+   height="12"
+   type="string"
+   left_pad="45"
+   length="1"
+   layout="topleft"
+   name="spellcheck_active"
+   width="175">
+      Active
+  </text>
+  <scroll_list
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="155"
+   layout="topleft"
+   left="55"
+   multi_select="true"
+   name="spellcheck_available_list"
+   sort_column="0"
+   sort_ascending="true" 
+   width="175" />
+  <button
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="26"
+   image_overlay="Arrow_Right"
+   hover_glow_amount="0.15"
+   layout="topleft"
+   left_pad="10"
+   name="spellcheck_moveright_btn"
+   top_delta="50"
+   width="25">
+  </button>
+  <button
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="26"
+   image_overlay="Arrow_Left"
+   hover_glow_amount="0.15"
+   layout="topleft"
+   name="spellcheck_moveleft_btn"
+   top_delta="30"
+   width="25">
+  </button>
+  <scroll_list
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="155"
+   layout="topleft"
+   left_pad="10"
+   multi_select="true"
+   name="spellcheck_active_list"
+   sort_column="0"
+   sort_ascending="true" 
+   top_pad="-105"
+   width="175"
+  />
+  <view_border
+   top_pad="10"
+   left="2"
+   height="0"
+   width="491"
+   follows="left|top"
+   bevel_style="none"
+   border_thickness="1"
+   mouse_opaque="false"
+   name="divisor4"/>
+  <button
+   top_pad="10"
+   right="380"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="spellcheck_ok"
+   label="OK" />
+  <button
+   top_delta="0"
+   right="480"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="spellcheck_cancel"
+   label="Cancel" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index caf7fc85f56..2e4c0ebbf55 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -216,4 +216,15 @@
    <button.commit_callback
     function="Pref.TranslationSettings" />
   </button>
+  <button
+   follows="top|left"
+   height="23"
+   layout="topleft"
+   top_pad="-23"
+   left_pad="5"
+   name="spellcheck_showgui"
+   commit_callback.function="Pref.SpellChecker"
+   label="Spell Checker Settings"
+   width="150">
+  </button>
 </panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_spellcheck.xml b/indra/newview/skins/default/xui/en/panel_preferences_spellcheck.xml
deleted file mode 100644
index f1b16c5d0d6..00000000000
--- a/indra/newview/skins/default/xui/en/panel_preferences_spellcheck.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Spell Check"
- layout="topleft"
- left="102"
- name="spellcheck"
- top="1"
- width="517">
-    <check_box
-     control_name="SpellCheck"
-     enabled="true"
-     follows="top|left"
-     height="16"
-     label="Enable spell checking"
-     layout="topleft"
-     left="30"
-     name="check_spellcheck"
-     top="30"
-     width="250"
-    />
-    <text
-     enabled_control="SpellCheck"
-     follows="top|left"
-     height="10"
-     label="Logs:"
-     layout="topleft"
-     left="55"
-     mouse_opaque="false"
-     name="text_spellcheck_dict"
-     top_pad="15"
-     type="string"
-     width="90"
-    >
-      Main dictionary :
-    </text>
-    <combo_box
-     enabled_control="SpellCheck"
-     follows="top|left"
-     height="23"
-     layout="topleft"
-     left_pad="10"
-     name="combo_spellcheck_dict"
-     top_pad="-15"
-     width="175"
-    />
-
-    <text
-     enabled_control="SpellCheck"
-     follows="top|left"
-     height="10"
-     label="Logs:"
-     layout="topleft"
-     left="55"
-     mouse_opaque="false"
-     name="text_spellcheck_additional"
-     top_pad="15"
-     type="string"
-     width="190"
-    >
-      Additional dictionaries :
-    </text>
-    <text
-     follows="top|left"
-     height="12"
-     layout="topleft"
-     left="80"
-     length="1"
-     name="text_spellcheck_available"
-     top_pad="10"
-     type="string"
-     width="175">
-        Available
-    </text>
-    <text
-     follows="top|left"
-     height="12"
-     type="string"
-     left_pad="45"
-     length="1"
-     layout="topleft"
-     name="text_spellcheck_active"
-     width="175">
-        Active
-    </text>
-    <scroll_list
-     enabled_control="SpellCheck"
-     follows="top|left"
-     height="155"
-     layout="topleft"
-     left="80"
-     multi_select="true"
-     name="list_spellcheck_available"
-     sort_column="0"
-     sort_ascending="true" 
-     width="175" />
-    <button
-     enabled_control="SpellCheck"
-     follows="top|left"
-     height="26"
-     image_overlay="Arrow_Right"
-     hover_glow_amount="0.15"
-     layout="topleft"
-     left_pad="10"
-     name="btn_spellcheck_moveright"
-     top_delta="50"
-     width="25">
-    </button>
-    <button
-     enabled_control="SpellCheck"
-     follows="top|left"
-     height="26"
-     image_overlay="Arrow_Left"
-     hover_glow_amount="0.15"
-     layout="topleft"
-     name="btn_spellcheck_moveleft"
-     top_delta="30"
-     width="25">
-    </button>
-    <scroll_list
-     enabled_control="SpellCheck"
-     follows="top|left"
-     height="155"
-     layout="topleft"
-     left_pad="10"
-     multi_select="true"
-     name="list_spellcheck_active"
-     sort_column="0"
-     sort_ascending="true" 
-     top_pad="-105"
-     width="175"
-    />
-
-</panel>
-- 
GitLab