summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt8
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/llappviewer.cpp15
-rw-r--r--[-rwxr-xr-x]indra/newview/llavatariconctrl.cpp0
-rwxr-xr-xindra/newview/llfloaterpreference.cpp7
-rw-r--r--indra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llfloaterspellchecksettings.cpp179
-rw-r--r--indra/newview/llfloaterspellchecksettings.h48
-rw-r--r--[-rwxr-xr-x]indra/newview/llmeshrepository.cpp0
-rw-r--r--indra/newview/llstartup.cpp1
-rw-r--r--indra/newview/llviewercontrol.cpp25
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp86
-rw-r--r--indra/newview/llviewermenu.h1
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
-rw-r--r--indra/newview/skins/default/textures/widgets/Arrow_Left.pngbin0 -> 311 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Arrow_Right.pngbin0 -> 313 bytes
-rw-r--r--indra/newview/skins/default/xui/en/floater_chat_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_notecard.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_spellcheck.xml175
-rw-r--r--indra/newview/skins/default/xui/en/menu_text_editor.xml79
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_chat.xml12
-rw-r--r--indra/newview/viewer_manifest.py13
27 files changed, 684 insertions, 1 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f8105f9a5a..cb4d265fef 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -13,6 +13,7 @@ include(EXPAT)
include(FMOD)
include(OPENAL)
include(FindOpenGL)
+include(Hunspell)
include(JsonCpp)
include(LLAudio)
include(LLCharacter)
@@ -72,6 +73,7 @@ include_directories(
${LLLOGIN_INCLUDE_DIRS}
${UPDATER_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
+ ${LIBS_PREBUILD_DIR}/include/hunspell
${OPENAL_LIB_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada/1.4
)
@@ -236,6 +238,7 @@ set(viewer_SOURCE_FILES
llfloatersidepanelcontainer.cpp
llfloatersnapshot.cpp
llfloatersounddevices.cpp
+ llfloaterspellchecksettings.cpp
llfloatertelehub.cpp
llfloatertestinspectors.cpp
llfloatertestlistview.cpp
@@ -794,6 +797,7 @@ set(viewer_HEADER_FILES
llfloatersidepanelcontainer.h
llfloatersnapshot.h
llfloatersounddevices.h
+ llfloaterspellchecksettings.h
llfloatertelehub.h
llfloatertestinspectors.h
llfloatertestlistview.h
@@ -1576,6 +1580,9 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcp100.dll
${SHARED_LIB_STAGING_DIR}/Debug/msvcr100d.dll
${SHARED_LIB_STAGING_DIR}/Debug/msvcp100d.dll
+ ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
+ ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
+ ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp.dll
@@ -1755,6 +1762,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${NDOF_LIBRARY}
+ ${HUNSPELL_LIBRARY}
${viewer_LIBRARIES}
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index bc5c293625..e8abcf4fc4 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12192,6 +12192,28 @@
<key>Value</key>
<real>10.0</real>
</map>
+ <key>SpellCheck</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable spellchecking on line and text editors</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>SpellCheckDictionary</key>
+ <map>
+ <key>Comment</key>
+ <string>Current primary and secondary dictionaries used for spell checking</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>English (United States),Second Life Glossary</string>
+ </map>
<key>UseNewWalkRun</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 1174d108d2..fac5416aab 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -93,6 +93,7 @@
#include "llsecondlifeurls.h"
#include "llupdaterservice.h"
#include "llcallfloater.h"
+#include "llspellcheck.h"
// Linden library includes
#include "llavatarnamecache.h"
@@ -114,6 +115,7 @@
// Third party library includes
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
@@ -2497,6 +2499,19 @@ bool LLAppViewer::initConfiguration()
//gDirUtilp->setSkinFolder("default");
}
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+ boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+ if (!dict_list.empty())
+ {
+ LLSpellChecker::setUseSpellCheck(dict_list.front());
+ dict_list.pop_front();
+ LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+ }
+ }
+
mYieldTime = gSavedSettings.getS32("YieldTime");
// Read skin/branding settings if specified.
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index b539ac38ed..b539ac38ed 100755..100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 2c383f09ba..e00184be23 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -347,6 +347,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.Proxy", boost::bind(&LLFloaterPreference::onClickProxySettings, this));
mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
+ mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
sSkin = gSavedSettings.getString("SkinCurrent");
@@ -935,7 +936,6 @@ void LLFloaterPreference::refreshSkin(void* data)
self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
}
-
void LLFloaterPreference::buildPopupLists()
{
LLScrollListCtrl& disabled_popups =
@@ -1524,6 +1524,11 @@ void LLFloaterPreference::onClickAutoReplace()
LLFloaterReg::showInstance("prefs_autoreplace");
}
+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 0b63002345..b71f7c647b 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -158,6 +158,7 @@ public:
void onClickProxySettings();
void onClickTranslationSettings();
void onClickAutoReplace();
+ void onClickSpellChecker();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
void getUIColor(LLUICtrl* ctrl, const LLSD& param);
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
new file mode 100644
index 0000000000..ff5afc8169
--- /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 0000000000..33c376fff6
--- /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/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index f461c7e46f..f461c7e46f 100755..100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0ac8c1fe39..c55b6302e4 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -739,6 +739,7 @@ bool idle_startup()
{
display_startup();
initialize_edit_menu();
+ initialize_spellcheck_menu();
display_startup();
init_menus();
display_startup();
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index ab45aae5cc..bb4e77fa9d 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -71,8 +71,12 @@
#include "llpaneloutfitsinventory.h"
#include "llpanellogin.h"
#include "llpaneltopinfobar.h"
+#include "llspellcheck.h"
#include "llupdaterservice.h"
+// Third party library includes
+#include <boost/algorithm/string.hpp>
+
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
BOOL gHackGodmode = FALSE;
#endif
@@ -508,6 +512,25 @@ bool handleForceShowGrid(const LLSD& newvalue)
return true;
}
+bool handleSpellCheckChanged()
+{
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+ boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+ if (!dict_list.empty())
+ {
+ LLSpellChecker::setUseSpellCheck(dict_list.front());
+ dict_list.pop_front();
+ LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+ return true;
+ }
+ }
+ LLSpellChecker::setUseSpellCheck(LLStringUtil::null);
+ return true;
+}
+
bool toggle_agent_pause(const LLSD& newvalue)
{
if ( newvalue.asBoolean() )
@@ -714,6 +737,8 @@ void settings_setup_listeners()
gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(boost::bind(&toggle_updater_service_active, _2));
gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
+ gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
+ gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index d66f742a70..d310e5a09a 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("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 714bf6b7e7..a475b71650 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -86,6 +86,7 @@
#include "llrootview.h"
#include "llsceneview.h"
#include "llselectmgr.h"
+#include "llspellcheckmenuhandler.h"
#include "llstatusbar.h"
#include "lltextureview.h"
#include "lltoolcomp.h"
@@ -5053,6 +5054,78 @@ class LLEditDelete : public view_listener_t
}
};
+void handle_spellcheck_replace_with_suggestion(const LLUICtrl* ctrl, const LLSD& param)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
+ {
+ return;
+ }
+
+ U32 index = 0;
+ if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
+ {
+ return;
+ }
+
+ spellcheck_handler->replaceWithSuggestion(index);
+}
+
+bool visible_spellcheck_suggestion(LLUICtrl* ctrl, const LLSD& param)
+{
+ LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(ctrl);
+ const LLContextMenu* menu = (item) ? dynamic_cast<const LLContextMenu*>(item->getParent()) : NULL;
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
+ {
+ return false;
+ }
+
+ U32 index = 0;
+ if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
+ {
+ return false;
+ }
+
+ item->setLabel(spellcheck_handler->getSuggestion(index));
+ return true;
+}
+
+void handle_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) )
+ {
+ spellcheck_handler->addToDictionary();
+ }
+}
+
+bool enable_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary());
+}
+
+void handle_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) )
+ {
+ spellcheck_handler->addToIgnore();
+ }
+}
+
+bool enable_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore());
+}
+
bool enable_object_delete()
{
bool new_value =
@@ -8003,6 +8076,19 @@ void initialize_edit_menu()
}
+void initialize_spellcheck_menu()
+{
+ LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
+ LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
+
+ commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2));
+ enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2));
+ commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1));
+ enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1));
+ commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1));
+ enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1));
+}
+
void initialize_menus()
{
// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 87cb4efbc4..8c40762865 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -39,6 +39,7 @@ class LLObjectSelection;
class LLSelectNode;
void initialize_edit_menu();
+void initialize_spellcheck_menu();
void init_menus();
void cleanup_menus();
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index eabcc68916..7ca6820318 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -54,6 +54,8 @@ with the same filename but different name
<texture name="Arrow_Down" file_name="widgets/Arrow_Down.png" preload="true" />
<texture name="Arrow_Up" file_name="widgets/Arrow_Up.png" preload="true" />
+ <texture name="Arrow_Left" file_name="widgets/Arrow_Left.png" preload="true" />
+ <texture name="Arrow_Right" file_name="widgets/Arrow_Right.png" preload="true" />
<texture name="AudioMute_Off" file_name="icons/AudioMute_Off.png" preload="false" />
<texture name="AudioMute_Over" file_name="icons/AudioMute_Over.png" preload="false" />
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Left.png b/indra/newview/skins/default/textures/widgets/Arrow_Left.png
new file mode 100644
index 0000000000..a424282839
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Right.png b/indra/newview/skins/default/textures/widgets/Arrow_Right.png
new file mode 100644
index 0000000000..e32bee8f34
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Right.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 688a01ce7b..405557242f 100644
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
@@ -46,6 +46,7 @@
left="0"
max_length_bytes="1023"
name="chat_box"
+ spellcheck="true"
text_pad_left="5"
text_pad_right="25"
tool_tip="Press Enter to say, Ctrl+Enter to shout"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index ca73883e53..8a73335261 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -83,6 +83,7 @@
label="To"
layout="bottomleft"
name="chat_editor"
+ spellcheck="true"
tab_group="3"
width="249">
</line_editor>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index be3b2d179d..2e1c8ce670 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -70,6 +70,7 @@
max_length="65536"
name="Notecard Editor"
parse_urls="false"
+ spellcheck="true"
tab_group="1"
top="46"
width="392"
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 0000000000..bd3f60cf4a
--- /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/menu_text_editor.xml b/indra/newview/skins/default/xui/en/menu_text_editor.xml
index fe8489166b..70b40dd89b 100644
--- a/indra/newview/skins/default/xui/en/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/menu_text_editor.xml
@@ -2,6 +2,85 @@
<context_menu
name="Text editor context menu">
<menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 1">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="0" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="0" />
+ </menu_item_call>
+ <menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 2">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="1" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="1" />
+ </menu_item_call>
+ <menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 3">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="2" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="2" />
+ </menu_item_call>
+ <menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 4">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="3" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="3" />
+ </menu_item_call>
+ <menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 5">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="4" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="4" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Suggestion Separator" />
+ <menu_item_call
+ label="Add to Dictionary"
+ layout="topleft"
+ name="Add to Dictionary">
+ <menu_item_call.on_click
+ function="SpellCheck.AddToDictionary" />
+ <menu_item_call.on_enable
+ function="SpellCheck.EnableAddToDictionary" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add to Ignore"
+ layout="topleft"
+ name="Add to Ignore">
+ <menu_item_call.on_click
+ function="SpellCheck.AddToIgnore" />
+ <menu_item_call.on_enable
+ function="SpellCheck.EnableAddToIgnore" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Spellcheck Separator" />
+ <menu_item_call
label="Cut"
layout="topleft"
name="Cut">
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 0faa1598b1..553c112e6f 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -134,6 +134,7 @@
top_pad="2"
max_length="1023"
name="pick_desc"
+ spellcheck="true"
text_color="black"
word_wrap="true" />
<text
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 607e1bb213..6d5fb51e85 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -141,6 +141,7 @@ Maximum 200 per group daily
max_length_bytes="63"
name="create_subject"
prevalidate_callback="ascii"
+ spellcheck="true"
width="218" />
<text
follows="left|top"
@@ -161,6 +162,7 @@ Maximum 200 per group daily
left_pad="3"
max_length="511"
name="create_message"
+ spellcheck="true"
top_delta="0"
width="218"
word_wrap="true" />
@@ -309,6 +311,7 @@ Maximum 200 per group daily
left_pad="3"
max_length_bytes="63"
name="view_subject"
+ spellcheck="true"
top_delta="-1"
visible="false"
width="200" />
@@ -333,6 +336,7 @@ Maximum 200 per group daily
right="-1"
max_length="511"
name="view_message"
+ spellcheck="true"
top_delta="-40"
width="313"
word_wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 21c627cdfb..6bc9c48729 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -19,6 +19,7 @@
left="0"
max_length_bytes="1023"
name="chat_box"
+ spellcheck="true"
text_pad_left="5"
text_pad_right="25"
tool_tip="Press Enter to say, Ctrl+Enter to shout"
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 364c12ddf4..4297c75d65 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -227,4 +227,16 @@
label="AutoReplace Settings"
width="150">
</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>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 9bf755c8f8..982dd34caf 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -91,6 +91,13 @@ class ViewerManifest(LLManifest):
# ... and the entire windlight directory
self.path("windlight")
+
+ # ... and the included spell checking dictionaries
+ pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
+ if self.prefix(src=pkgdir,dst=""):
+ self.path("dictionaries")
+ self.end_prefix(pkgdir)
+
self.end_prefix("app_settings")
if self.prefix(src="character"):
@@ -393,6 +400,9 @@ class WindowsManifest(ViewerManifest):
self.path("ssleay32.dll")
self.path("libeay32.dll")
+ # Hunspell
+ self.path("libhunspell.dll")
+
# For google-perftools tcmalloc allocator.
try:
if self.args['configuration'].lower() == 'debug':
@@ -659,6 +669,7 @@ class DarwinManifest(ViewerManifest):
# copy additional libs in <bundle>/Contents/MacOS/
self.path("../packages/lib/release/libndofdev.dylib", dst="Resources/libndofdev.dylib")
+ self.path("../packages/lib/release/libhunspell-1.3.0.dylib", dst="Resources/libhunspell-1.3.0.dylib")
self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install")
@@ -1057,6 +1068,8 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libopenjpeg.so.1.4.0")
self.path("libopenjpeg.so.1")
self.path("libopenjpeg.so")
+ self.path("libhunspell-1.3.so")
+ self.path("libhunspell-1.3.so.0")
self.path("libalut.so")
self.path("libopenal.so", "libopenal.so.1")
self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname