summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt5
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/llappviewer.cpp14
-rw-r--r--[-rwxr-xr-x]indra/newview/llavatariconctrl.cpp0
-rw-r--r--indra/newview/llstartup.cpp1
-rw-r--r--indra/newview/llviewercontrol.cpp24
-rw-r--r--indra/newview/llviewermenu.cpp86
-rw-r--r--indra/newview/llviewermenu.h1
-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/menu_text_editor.xml79
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml1
-rw-r--r--indra/newview/viewer_manifest.py8
13 files changed, 243 insertions, 0 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6b2fe1e45a..bb0c4a9979 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -71,6 +71,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
)
@@ -1566,6 +1567,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
@@ -1745,6 +1749,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 1ea623791d..1ad3ee1dd1 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12082,6 +12082,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)</string>
+ </map>
<key>UseNewWalkRun</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 40136adbc9..d185215a9e 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -91,6 +91,7 @@
#include "llsecondlifeurls.h"
#include "llupdaterservice.h"
#include "llcallfloater.h"
+#include "llspellcheck.h"
// Linden library includes
#include "llavatarnamecache.h"
@@ -112,6 +113,7 @@
// Third party library includes
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
@@ -2490,6 +2492,18 @@ bool LLAppViewer::initConfiguration()
//gDirUtilp->setSkinFolder("default");
}
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ boost::split(dict_list, gSavedSettings.getString("SpellCheckDictionary"), 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/llstartup.cpp b/indra/newview/llstartup.cpp
index 7e02a41e7e..89360778d1 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 093b84413a..7b6dbfaa0b 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
@@ -498,6 +502,24 @@ bool handleForceShowGrid(const LLSD& newvalue)
return true;
}
+bool handleSpellCheckChanged()
+{
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ boost::split(dict_list, gSavedSettings.getString("SpellCheckDictionary"), 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() )
@@ -704,6 +726,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/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 0104d35e53..2a11f3cc16 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -81,6 +81,7 @@
#include "llrootview.h"
#include "llsceneview.h"
#include "llselectmgr.h"
+#include "llspellcheckmenuhandler.h"
#include "llstatusbar.h"
#include "lltextureview.h"
#include "lltoolcomp.h"
@@ -4984,6 +4985,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 =
@@ -7933,6 +8006,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/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 63992462b3..32a2c26cf0 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 a2739a8339..2f3788ec3d 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -84,6 +84,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/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_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/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 0931c4ec9b..1b732676e4 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -91,6 +91,8 @@ class ViewerManifest(LLManifest):
# ... and the entire windlight directory
self.path("windlight")
+ # ... and the pre-installed spell checking dictionaries
+ self.path("dictionaries")
self.end_prefix("app_settings")
if self.prefix(src="character"):
@@ -393,6 +395,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 +664,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.dylib", dst="Resources/libhunspell-1.3.dylib")
self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install")
@@ -1053,6 +1059,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