diff options
Diffstat (limited to 'indra/newview')
24 files changed, 527 insertions, 0 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3c9bde34b7..24d643f260 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) @@ -71,6 +72,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 ) @@ -1571,6 +1573,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 @@ -1750,6 +1755,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 ee8c15752b..462a26e05b 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12159,6 +12159,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 173b0e538c..c096537de6 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -66,6 +66,7 @@ #include "llsky.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" +#include "llspellcheck.h" #include "llsliderctrl.h" #include "lltabcontainer.h" #include "lltrans.h" @@ -110,6 +111,8 @@ #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; @@ -445,6 +448,11 @@ 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) { @@ -577,6 +585,24 @@ 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) @@ -687,6 +713,8 @@ 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(); @@ -866,6 +894,25 @@ 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")); @@ -931,6 +978,83 @@ 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() { diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index ec5994e917..af10af7f48 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -121,6 +121,7 @@ public: 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); @@ -161,6 +162,7 @@ public: 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/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index bd20210190..bd20210190 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 093b84413a..d7168a401c 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,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() ) @@ -704,6 +727,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 12aed8f448..6ed2d78edf 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" @@ -5011,6 +5012,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 = @@ -7954,6 +8027,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 Binary files differnew file mode 100644 index 0000000000..a424282839 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Arrow_Left.png diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Right.png b/indra/newview/skins/default/textures/widgets/Arrow_Right.png Binary files differnew file mode 100644 index 0000000000..e32bee8f34 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Arrow_Right.png 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 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_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index b2662331b0..bcfbe8d873 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -120,6 +120,12 @@ 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_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/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_spellcheck.xml b/indra/newview/skins/default/xui/en/panel_preferences_spellcheck.xml new file mode 100644 index 0000000000..f1b16c5d0d --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_preferences_spellcheck.xml @@ -0,0 +1,136 @@ +<?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> 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 |