diff options
author | McCabe Maxsted | 2010-09-29 16:16:59 -0700 |
---|---|---|
committer | McCabe Maxsted | 2010-09-29 16:16:59 -0700 |
commit | c9b90f87a6837ba05465bca8cf245d63b0a1506a (patch) | |
tree | 18c65158095501fcb73ef4ab6389933f9b3d93f8 | |
parent | Fix for Bug #544 (diff) | |
parent | Context menu translator: (diff) | |
download | meta-impy-c9b90f87a6837ba05465bca8cf245d63b0a1506a.zip meta-impy-c9b90f87a6837ba05465bca8cf245d63b0a1506a.tar.gz meta-impy-c9b90f87a6837ba05465bca8cf245d63b0a1506a.tar.bz2 meta-impy-c9b90f87a6837ba05465bca8cf245d63b0a1506a.tar.xz |
Merge remote branch 'thickbrick/translate_fixes_b' into weekly
-rw-r--r-- | linden/indra/llui/lllineeditor.cpp | 251 | ||||
-rw-r--r-- | linden/indra/llui/lllineeditor.h | 24 | ||||
-rw-r--r-- | linden/indra/llui/lltexteditor.cpp | 236 | ||||
-rw-r--r-- | linden/indra/llui/lltexteditor.h | 17 | ||||
-rw-r--r-- | linden/indra/newview/lgghunspell_wrapper.cpp | 18 | ||||
-rw-r--r-- | linden/indra/newview/lgghunspell_wrapper.h | 4 | ||||
-rwxr-xr-x | linden/indra/newview/llviewermessage.cpp | 45 | ||||
-rw-r--r-- | linden/indra/newview/llviewermessage.h | 2 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/panel_login.xml | 9 |
9 files changed, 410 insertions, 196 deletions
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 66ef4c6..49fe3be 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp | |||
@@ -96,23 +96,23 @@ static LLRegisterWidget<LLLineEditor> r1("line_editor"); | |||
96 | class LineChatTranslationReceiver : public LLTranslate::TranslationReceiver | 96 | class LineChatTranslationReceiver : public LLTranslate::TranslationReceiver |
97 | { | 97 | { |
98 | public : | 98 | public : |
99 | LineChatTranslationReceiver(const std::string &toLang, LLLineEditor* line): LLTranslate::TranslationReceiver("", toLang), | 99 | LineChatTranslationReceiver(const std::string &toLang, LLLineEditor* line, const S32 start, const S32 len): |
100 | m_line(line) | 100 | LLTranslate::TranslationReceiver("", toLang), |
101 | m_line(line), | ||
102 | m_position(start), | ||
103 | m_origLength(len) | ||
101 | { | 104 | { |
102 | } | 105 | } |
103 | 106 | ||
104 | static boost::intrusive_ptr<LineChatTranslationReceiver> build(const std::string &toLang,LLLineEditor* line) | 107 | static boost::intrusive_ptr<LineChatTranslationReceiver> build(const std::string &toLang,LLLineEditor* line, const S32 start, const S32 len) |
105 | { | 108 | { |
106 | return boost::intrusive_ptr<LineChatTranslationReceiver>(new LineChatTranslationReceiver(toLang,line)); | 109 | return boost::intrusive_ptr<LineChatTranslationReceiver>(new LineChatTranslationReceiver(toLang, line, start, len)); |
107 | } | 110 | } |
108 | 111 | ||
109 | protected: | 112 | protected: |
110 | void handleResponse(const std::string &translation, const std::string &detectedLanguage) | 113 | void handleResponse(const std::string &translation, const std::string &detectedLanguage) |
111 | { | 114 | { |
112 | static BOOL* rep = rebind_llcontrol<BOOL>("EmeraldTranslateReplace", &gSavedSettings, true); | 115 | m_line->translationReplace(translation, m_position, m_origLength); |
113 | if(*rep) | ||
114 | m_line->deleteSelection(); | ||
115 | m_line->insert(((*rep)?"":" (") + translation + ((*rep)?"":")"),m_line->getCursor()); | ||
116 | } | 116 | } |
117 | void handleFailure() | 117 | void handleFailure() |
118 | { | 118 | { |
@@ -120,6 +120,8 @@ protected: | |||
120 | } | 120 | } |
121 | private: | 121 | private: |
122 | LLLineEditor* m_line; | 122 | LLLineEditor* m_line; |
123 | S32 m_position; | ||
124 | S32 m_origLength; | ||
123 | }; | 125 | }; |
124 | 126 | ||
125 | LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | 127 | LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, |
@@ -151,6 +153,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | |||
151 | mLastSelectionY(-1), | 153 | mLastSelectionY(-1), |
152 | mLastSelectionStart(-1), | 154 | mLastSelectionStart(-1), |
153 | mLastSelectionEnd(-1), | 155 | mLastSelectionEnd(-1), |
156 | mLastContextMenuX(-1), | ||
154 | mPrevalidateFunc( prevalidate_func ), | 157 | mPrevalidateFunc( prevalidate_func ), |
155 | mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ), | 158 | mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ), |
156 | mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ), | 159 | mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ), |
@@ -172,7 +175,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | |||
172 | mImage( sImage ), | 175 | mImage( sImage ), |
173 | mReplaceNewlinesWithSpaces( TRUE ), | 176 | mReplaceNewlinesWithSpaces( TRUE ), |
174 | mSpellCheckable( FALSE ), | 177 | mSpellCheckable( FALSE ), |
175 | mShowMisspellings(FALSE) | 178 | mAllowTranslate(TRUE) |
176 | { | 179 | { |
177 | llassert( max_length_bytes > 0 ); | 180 | llassert( max_length_bytes > 0 ); |
178 | 181 | ||
@@ -211,12 +214,6 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | |||
211 | } | 214 | } |
212 | mImage = sImage; | 215 | mImage = sImage; |
213 | 216 | ||
214 | // in other words, highlighting requires a restart | ||
215 | if (glggHunSpell->getSpellCheckHighlight()) | ||
216 | { | ||
217 | mShowMisspellings = TRUE; | ||
218 | } | ||
219 | |||
220 | // make the popup menu available | 217 | // make the popup menu available |
221 | //LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view); | 218 | //LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view); |
222 | LLMenuGL* menu = new LLMenuGL("wot"); | 219 | LLMenuGL* menu = new LLMenuGL("wot"); |
@@ -224,46 +221,49 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | |||
224 | { | 221 | { |
225 | menu = new LLMenuGL(LLStringUtil::null); | 222 | menu = new LLMenuGL(LLStringUtil::null); |
226 | }*/ | 223 | }*/ |
227 | menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this)); | 224 | |
228 | menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this)); | 225 | menu->append(new LLMenuItemCallGL("Cut", context_cut, context_enable_cut, this)); |
229 | menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this)); | 226 | menu->append(new LLMenuItemCallGL("Copy", context_copy, context_enable_copy, this)); |
230 | menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this)); | 227 | menu->append(new LLMenuItemCallGL("Paste", context_paste, context_enable_paste, this)); |
231 | menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this)); | 228 | menu->append(new LLMenuItemCallGL("Delete", context_delete, context_enable_delete, this)); |
229 | menu->append(new LLMenuItemCallGL("Select All", context_selectall, context_enable_selectall, this)); | ||
230 | |||
232 | menu->appendSeparator("Transep"); | 231 | menu->appendSeparator("Transep"); |
233 | LLMenuGL* translatemenu = new LLMenuGL("Translate To"); | 232 | LLMenuGL* translatemenu = new LLMenuGL("Translate To"); |
234 | translatemenu->setCanTearOff(FALSE); | 233 | translatemenu->setCanTearOff(FALSE); |
235 | SpellMenuBind* t=new SpellMenuBind;t->origin=this;t->word="en"; | 234 | SpellMenuBind* t=new SpellMenuBind;t->origin=this;t->word="en"; |
236 | translatemenu->append(new LLMenuItemCallGL("English",translateText, NULL, t)); | 235 | translatemenu->append(new LLMenuItemCallGL("English", context_translate, context_enable_translate, t)); |
237 | t=new SpellMenuBind;t->origin=this;t->word="da"; | 236 | t=new SpellMenuBind;t->origin=this;t->word="da"; |
238 | translatemenu->append(new LLMenuItemCallGL("Danish",translateText, NULL, t)); | 237 | translatemenu->append(new LLMenuItemCallGL("Danish", context_translate, context_enable_translate, t)); |
239 | t=new SpellMenuBind;t->origin=this;t->word="de"; | 238 | t=new SpellMenuBind;t->origin=this;t->word="de"; |
240 | translatemenu->append(new LLMenuItemCallGL("Deutsch(German)",translateText, NULL, t)); | 239 | translatemenu->append(new LLMenuItemCallGL("Deutsch(German)", context_translate, context_enable_translate, t)); |
241 | t=new SpellMenuBind;t->origin=this;t->word="es"; | 240 | t=new SpellMenuBind;t->origin=this;t->word="es"; |
242 | translatemenu->append(new LLMenuItemCallGL("Spanish",translateText, NULL, t)); | 241 | translatemenu->append(new LLMenuItemCallGL("Spanish", context_translate, context_enable_translate, t)); |
243 | t=new SpellMenuBind;t->origin=this;t->word="fr"; | 242 | t=new SpellMenuBind;t->origin=this;t->word="fr"; |
244 | translatemenu->append(new LLMenuItemCallGL("French",translateText, NULL, t)); | 243 | translatemenu->append(new LLMenuItemCallGL("French", context_translate, context_enable_translate, t)); |
245 | t=new SpellMenuBind;t->origin=this;t->word="it"; | 244 | t=new SpellMenuBind;t->origin=this;t->word="it"; |
246 | translatemenu->append(new LLMenuItemCallGL("Italian",translateText, NULL, t)); | 245 | translatemenu->append(new LLMenuItemCallGL("Italian", context_translate, context_enable_translate, t)); |
247 | t=new SpellMenuBind;t->origin=this;t->word="hu"; | 246 | t=new SpellMenuBind;t->origin=this;t->word="hu"; |
248 | translatemenu->append(new LLMenuItemCallGL("Hungarian",translateText, NULL, t)); | 247 | translatemenu->append(new LLMenuItemCallGL("Hungarian", context_translate, context_enable_translate, t)); |
249 | t=new SpellMenuBind;t->origin=this;t->word="nl"; | 248 | t=new SpellMenuBind;t->origin=this;t->word="nl"; |
250 | translatemenu->append(new LLMenuItemCallGL("Dutch",translateText, NULL, t)); | 249 | translatemenu->append(new LLMenuItemCallGL("Dutch", context_translate, context_enable_translate, t)); |
251 | t=new SpellMenuBind;t->origin=this;t->word="pl"; | 250 | t=new SpellMenuBind;t->origin=this;t->word="pl"; |
252 | translatemenu->append(new LLMenuItemCallGL("Polish",translateText, NULL, t)); | 251 | translatemenu->append(new LLMenuItemCallGL("Polish", context_translate, context_enable_translate, t)); |
253 | t=new SpellMenuBind;t->origin=this;t->word="pt"; | 252 | t=new SpellMenuBind;t->origin=this;t->word="pt"; |
254 | translatemenu->append(new LLMenuItemCallGL("Portugese",translateText, NULL, t)); | 253 | translatemenu->append(new LLMenuItemCallGL("Portugese", context_translate, context_enable_translate, t)); |
255 | t=new SpellMenuBind;t->origin=this;t->word="ru"; | 254 | t=new SpellMenuBind;t->origin=this;t->word="ru"; |
256 | translatemenu->append(new LLMenuItemCallGL("Russian",translateText, NULL, t)); | 255 | translatemenu->append(new LLMenuItemCallGL("Russian", context_translate, context_enable_translate, t)); |
257 | t=new SpellMenuBind;t->origin=this;t->word="tr"; | 256 | t=new SpellMenuBind;t->origin=this;t->word="tr"; |
258 | translatemenu->append(new LLMenuItemCallGL("Turkish",translateText, NULL, t)); | 257 | translatemenu->append(new LLMenuItemCallGL("Turkish", context_translate, context_enable_translate, t)); |
259 | t=new SpellMenuBind;t->origin=this;t->word="uk"; | 258 | t=new SpellMenuBind;t->origin=this;t->word="uk"; |
260 | translatemenu->append(new LLMenuItemCallGL("Ukrainian",translateText, NULL, t)); | 259 | translatemenu->append(new LLMenuItemCallGL("Ukrainian", context_translate, context_enable_translate, t)); |
261 | t=new SpellMenuBind;t->origin=this;t->word="zh"; | 260 | t=new SpellMenuBind;t->origin=this;t->word="zh"; |
262 | translatemenu->append(new LLMenuItemCallGL("Chinese",translateText, NULL, t)); | 261 | translatemenu->append(new LLMenuItemCallGL("Chinese", context_translate, context_enable_translate, t)); |
263 | t=new SpellMenuBind;t->origin=this;t->word="ja"; | 262 | t=new SpellMenuBind;t->origin=this;t->word="ja"; |
264 | translatemenu->append(new LLMenuItemCallGL("Japanese",translateText, NULL, t)); | 263 | translatemenu->append(new LLMenuItemCallGL("Japanese", context_translate, context_enable_translate, t)); |
265 | t=new SpellMenuBind;t->origin=this;t->word="ko"; | 264 | t=new SpellMenuBind;t->origin=this;t->word="ko"; |
266 | translatemenu->append(new LLMenuItemCallGL("Korean",translateText, NULL, t)); | 265 | translatemenu->append(new LLMenuItemCallGL("Korean", context_translate, context_enable_translate, t)); |
266 | |||
267 | menu->appendMenu(translatemenu); | 267 | menu->appendMenu(translatemenu); |
268 | menu->appendSeparator("Spelsep"); | 268 | menu->appendSeparator("Spelsep"); |
269 | //menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); | 269 | //menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); |
@@ -439,7 +439,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) | |||
439 | 439 | ||
440 | 440 | ||
441 | // Picks a new cursor position based on the actual screen size of text being drawn. | 441 | // Picks a new cursor position based on the actual screen size of text being drawn. |
442 | S32 LLLineEditor::calculateCursorFromMouse( S32 local_mouse_x ) | 442 | S32 LLLineEditor::calculateCursorFromMouse( S32 local_mouse_x ) const |
443 | { | 443 | { |
444 | const llwchar* wtext = mText.getWString().c_str(); | 444 | const llwchar* wtext = mText.getWString().c_str(); |
445 | LLWString asterix_text; | 445 | LLWString asterix_text; |
@@ -517,17 +517,30 @@ void LLLineEditor::deselect() | |||
517 | mIsSelecting = FALSE; | 517 | mIsSelecting = FALSE; |
518 | } | 518 | } |
519 | 519 | ||
520 | BOOL LLLineEditor::context_enable_cut(void* data) | ||
521 | { | ||
522 | LLLineEditor* line = (LLLineEditor*)data; | ||
523 | return (line && line->canCut()); | ||
524 | } | ||
520 | 525 | ||
521 | void LLLineEditor::context_cut(void* data) | 526 | void LLLineEditor::context_cut(void* data) |
522 | { | 527 | { |
523 | LLLineEditor* line = (LLLineEditor*)data; | 528 | LLLineEditor* line = (LLLineEditor*)data; |
524 | if(line)line->cut(); | 529 | if(line)line->cut(); |
525 | } | 530 | } |
531 | |||
532 | BOOL LLLineEditor::context_enable_copy(void* data) | ||
533 | { | ||
534 | LLLineEditor* line = (LLLineEditor*)data; | ||
535 | return (line &&line->canCopy()); | ||
536 | } | ||
537 | |||
526 | void LLLineEditor::context_copy(void* data) | 538 | void LLLineEditor::context_copy(void* data) |
527 | { | 539 | { |
528 | LLLineEditor* line = (LLLineEditor*)data; | 540 | LLLineEditor* line = (LLLineEditor*)data; |
529 | if(line)line->copy(); | 541 | if(line)line->copy(); |
530 | } | 542 | } |
543 | |||
531 | void LLLineEditor::spell_correct(void* data) | 544 | void LLLineEditor::spell_correct(void* data) |
532 | { | 545 | { |
533 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | 546 | SpellMenuBind* tempBind = (SpellMenuBind*)data; |
@@ -539,31 +552,52 @@ void LLLineEditor::spell_correct(void* data) | |||
539 | 552 | ||
540 | } | 553 | } |
541 | } | 554 | } |
542 | void LLLineEditor::translateText(void * data) | 555 | |
556 | BOOL LLLineEditor::context_enable_translate(void* data) | ||
557 | { | ||
558 | SpellMenuBind* t = (SpellMenuBind*)data; | ||
559 | return (t && t->origin && t->origin->canTranslate()); | ||
560 | } | ||
561 | |||
562 | void LLLineEditor::context_translate(void * data) | ||
543 | { | 563 | { |
544 | SpellMenuBind* t = (SpellMenuBind*)data; | 564 | SpellMenuBind* t = (SpellMenuBind*)data; |
545 | LLLineEditor* line = t->origin; | 565 | LLLineEditor* line = t->origin; |
546 | const std::string &toLang = t->word;//LLTranslate::getTranslateLanguage(); | 566 | const std::string &toLang = t->word;//LLTranslate::getTranslateLanguage(); |
547 | LLHTTPClient::ResponderPtr result = LineChatTranslationReceiver::build(toLang,line); | 567 | |
548 | S32 left_pos = llmin( line->mSelectionStart, line->mSelectionEnd ); | 568 | bool has_text = false; |
549 | S32 length = abs( line->mSelectionStart - line->mSelectionEnd ); | 569 | S32 start, length; |
550 | LLTranslate::translateMessage(result,"", toLang, line->mText.getString().substr(left_pos, length)); | 570 | if (line->hasSelection()) |
571 | { | ||
572 | // translate selection | ||
573 | start = llmin(line->mSelectionStart, line->mSelectionEnd); | ||
574 | length = abs(line->mSelectionEnd - line->mSelectionStart); | ||
575 | has_text = length > 0; | ||
576 | } | ||
577 | else | ||
578 | { | ||
579 | // translate one word at click position | ||
580 | S32 at = line->calculateCursorFromMouse(line->mLastContextMenuX); | ||
581 | has_text = line->getWordBoundriesAt(at, &start, &length); | ||
582 | } | ||
583 | |||
584 | if (has_text) | ||
585 | { | ||
586 | std::string to_translate = wstring_to_utf8str(line->getWText().substr(start, length)); | ||
587 | LLHTTPClient::ResponderPtr result = LineChatTranslationReceiver::build(toLang, line, start, length); | ||
588 | LLTranslate::translateMessage(result,"", toLang, to_translate); | ||
589 | } | ||
551 | } | 590 | } |
591 | |||
552 | void LLLineEditor::spell_show(void * data) | 592 | void LLLineEditor::spell_show(void * data) |
553 | { | 593 | { |
554 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | 594 | SpellMenuBind* tempBind = (SpellMenuBind*)data; |
555 | LLLineEditor* line = tempBind->origin; | 595 | LLLineEditor* line = tempBind->origin; |
556 | 596 | ||
557 | if( tempBind && line) | 597 | if (tempBind && line) |
558 | { | 598 | { |
559 | if (tempBind->word == "Show Misspellings") | 599 | BOOL show = (tempBind->word == "Show Misspellings"); |
560 | { | 600 | glggHunSpell->setSpellCheckHighlight(show); |
561 | line->mShowMisspellings = TRUE; | ||
562 | } | ||
563 | else | ||
564 | { | ||
565 | line->mShowMisspellings = FALSE; | ||
566 | } | ||
567 | } | 601 | } |
568 | } | 602 | } |
569 | 603 | ||
@@ -623,18 +657,36 @@ void LLLineEditor::spell_add(void* data) | |||
623 | } | 657 | } |
624 | } | 658 | } |
625 | 659 | ||
660 | BOOL LLLineEditor::context_enable_paste(void* data) | ||
661 | { | ||
662 | LLLineEditor* line = (LLLineEditor*)data; | ||
663 | return (line && line->canPaste()); | ||
664 | } | ||
665 | |||
626 | void LLLineEditor::context_paste(void* data) | 666 | void LLLineEditor::context_paste(void* data) |
627 | { | 667 | { |
628 | LLLineEditor* line = (LLLineEditor*)data; | 668 | LLLineEditor* line = (LLLineEditor*)data; |
629 | if(line)line->paste(); | 669 | if(line)line->paste(); |
630 | } | 670 | } |
631 | 671 | ||
672 | BOOL LLLineEditor::context_enable_delete(void* data) | ||
673 | { | ||
674 | LLLineEditor* line = (LLLineEditor*)data; | ||
675 | return (line && line->canDoDelete()); | ||
676 | } | ||
677 | |||
632 | void LLLineEditor::context_delete(void* data) | 678 | void LLLineEditor::context_delete(void* data) |
633 | { | 679 | { |
634 | LLLineEditor* line = (LLLineEditor*)data; | 680 | LLLineEditor* line = (LLLineEditor*)data; |
635 | if(line)line->doDelete(); | 681 | if(line)line->doDelete(); |
636 | } | 682 | } |
637 | 683 | ||
684 | BOOL LLLineEditor::context_enable_selectall(void* data) | ||
685 | { | ||
686 | LLLineEditor* line = (LLLineEditor*)data; | ||
687 | return (line && line->canSelectAll()); | ||
688 | } | ||
689 | |||
638 | void LLLineEditor::context_selectall(void* data) | 690 | void LLLineEditor::context_selectall(void* data) |
639 | { | 691 | { |
640 | LLLineEditor* line = (LLLineEditor*)data; | 692 | LLLineEditor* line = (LLLineEditor*)data; |
@@ -738,7 +790,8 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
738 | 790 | ||
739 | //setCursorAtLocalPos( x); | 791 | //setCursorAtLocalPos( x); |
740 | S32 wordStart = 0; | 792 | S32 wordStart = 0; |
741 | S32 wordEnd = calculateCursorFromMouse(x); | 793 | S32 wordEnd = 0; |
794 | S32 pos = calculateCursorFromMouse(x); | ||
742 | 795 | ||
743 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | 796 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); |
744 | if (menu) | 797 | if (menu) |
@@ -761,36 +814,21 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
761 | } | 814 | } |
762 | suggestionMenuItems.clear(); | 815 | suggestionMenuItems.clear(); |
763 | 816 | ||
764 | menu->setItemVisible("Translate To", !mReadOnly); | ||
765 | menu->setItemVisible("Transep", !mReadOnly); | ||
766 | |||
767 | // spell_check="true" in xui | 817 | // spell_check="true" in xui |
818 | menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable); | ||
768 | if (!mReadOnly && mSpellCheckable) | 819 | if (!mReadOnly && mSpellCheckable) |
769 | { | 820 | { |
770 | const LLWString& text = mText.getWString(); | ||
771 | |||
772 | // search for word matches | 821 | // search for word matches |
773 | if (LLTextEditor::isPartOfWord(text[wordEnd])) | 822 | bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordEnd); |
823 | if (is_word_part) | ||
774 | { | 824 | { |
775 | // Select word the cursor is over | 825 | const LLWString& text = mText.getWString(); |
776 | while ((wordEnd > 0) && LLTextEditor::isPartOfWord(text[wordEnd-1])) | ||
777 | { | ||
778 | wordEnd--; | ||
779 | } | ||
780 | wordStart = wordEnd; | ||
781 | //startSelection(); | ||
782 | |||
783 | while ((wordEnd < (S32)text.length()) && LLTextEditor::isPartOfWord( text[wordEnd] ) ) | ||
784 | { | ||
785 | wordEnd++; | ||
786 | } | ||
787 | std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart)); | 826 | std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart)); |
788 | 827 | ||
789 | if (!glggHunSpell->isSpelledRight(selectedWord)) | 828 | if (!glggHunSpell->isSpelledRight(selectedWord)) |
790 | { | 829 | { |
791 | //misspelled word here, and you have just right clicked on it! | 830 | //misspelled word here, and you have just right clicked on it! |
792 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); | 831 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); |
793 | //menu->setItemVisible("Transep",(suggs.size()>0)); | ||
794 | 832 | ||
795 | for (int i = 0; i<(int)suggs.size() ;i++) | 833 | for (int i = 0; i<(int)suggs.size() ;i++) |
796 | { | 834 | { |
@@ -821,7 +859,7 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
821 | 859 | ||
822 | SpellMenuBind * tempStruct = new SpellMenuBind; | 860 | SpellMenuBind * tempStruct = new SpellMenuBind; |
823 | tempStruct->origin = this; | 861 | tempStruct->origin = this; |
824 | if (mShowMisspellings) | 862 | if (glggHunSpell->getSpellCheckHighlight()) |
825 | { | 863 | { |
826 | tempStruct->word = "Hide Misspellings"; | 864 | tempStruct->word = "Hide Misspellings"; |
827 | } | 865 | } |
@@ -836,6 +874,7 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
836 | menu->append(suggMenuItem); | 874 | menu->append(suggMenuItem); |
837 | } | 875 | } |
838 | 876 | ||
877 | mLastContextMenuX = x; | ||
839 | menu->buildDrawLabels(); | 878 | menu->buildDrawLabels(); |
840 | menu->updateParent(LLMenuGL::sMenuContainer); | 879 | menu->updateParent(LLMenuGL::sMenuContainer); |
841 | LLMenuGL::showPopup(this, menu, x, y); | 880 | LLMenuGL::showPopup(this, menu, x, y); |
@@ -1109,13 +1148,9 @@ void LLLineEditor::setSelection(S32 start, S32 end) | |||
1109 | { | 1148 | { |
1110 | S32 len = mText.length(); | 1149 | S32 len = mText.length(); |
1111 | 1150 | ||
1112 | mIsSelecting = TRUE; | 1151 | mSelectionStart = llclamp(start, 0, len); |
1113 | 1152 | mSelectionEnd = llclamp(end, 0, len); | |
1114 | // JC, yes, this seems odd, but I think you have to presume a | 1153 | setCursor(end); |
1115 | // selection dragged from the end towards the start. | ||
1116 | mSelectionStart = llclamp(end, 0, len); | ||
1117 | mSelectionEnd = llclamp(start, 0, len); | ||
1118 | setCursor(start); | ||
1119 | } | 1154 | } |
1120 | 1155 | ||
1121 | void LLLineEditor::setDrawAsterixes(BOOL b) | 1156 | void LLLineEditor::setDrawAsterixes(BOOL b) |
@@ -1152,6 +1187,26 @@ S32 LLLineEditor::nextWordPos(S32 cursorPos) const | |||
1152 | return cursorPos; | 1187 | return cursorPos; |
1153 | } | 1188 | } |
1154 | 1189 | ||
1190 | BOOL LLLineEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const | ||
1191 | { | ||
1192 | const LLWString& wtext = mText.getWString(); | ||
1193 | S32 pos = at; | ||
1194 | if (LLTextEditor::isPartOfWord(wtext[pos])) | ||
1195 | { | ||
1196 | while ( (pos > 0) && LLTextEditor::isPartOfWord(wtext[pos - 1]) ) | ||
1197 | { | ||
1198 | pos--; | ||
1199 | } | ||
1200 | *word_begin = pos; | ||
1201 | while ( (pos < wtext.length()) && LLTextEditor::isPartOfWord(wtext[pos]) ) | ||
1202 | { | ||
1203 | pos++; | ||
1204 | } | ||
1205 | *word_length = pos - *word_begin; | ||
1206 | return TRUE; | ||
1207 | } | ||
1208 | return FALSE; | ||
1209 | } | ||
1155 | 1210 | ||
1156 | BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) | 1211 | BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) |
1157 | { | 1212 | { |
@@ -1315,6 +1370,37 @@ void LLLineEditor::spellReplace(SpellMenuBind* spellData) | |||
1315 | 1370 | ||
1316 | 1371 | ||
1317 | } | 1372 | } |
1373 | |||
1374 | void LLLineEditor::translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length) | ||
1375 | { | ||
1376 | //*TODO: should probably check if the content was modified since the http query | ||
1377 | // was made, so we don't insert text in the wrong place. | ||
1378 | BOOL replace = gSavedSettings.getBOOL("EmeraldTranslateReplace"); | ||
1379 | std::string text = replace ? translation : " (" + translation + ")"; | ||
1380 | S32 pos = replace ? orig_start : orig_start + orig_length; | ||
1381 | if (replace) | ||
1382 | { | ||
1383 | mText.erase(orig_start, orig_length); | ||
1384 | } | ||
1385 | insert(text, pos); | ||
1386 | |||
1387 | S32 text_wlen = utf8str_to_wstring(text).length(); | ||
1388 | if (hasSelection()) | ||
1389 | { | ||
1390 | setSelection(pos, pos + text_wlen); | ||
1391 | } | ||
1392 | setCursor(pos + text_wlen); | ||
1393 | } | ||
1394 | |||
1395 | BOOL LLLineEditor::canTranslate() const | ||
1396 | { | ||
1397 | // if allow_translate="true" in xui, and if other factors permit, we allow it | ||
1398 | S32 pos = calculateCursorFromMouse(mLastContextMenuX); | ||
1399 | const LLWString& wtext = getWText(); | ||
1400 | bool is_word_part = (pos > -1) && LLTextEditor::isPartOfWord(wtext[pos]); | ||
1401 | return (mAllowTranslate && !mReadOnly && (is_word_part || hasSelection())); | ||
1402 | } | ||
1403 | |||
1318 | void LLLineEditor::insert(std::string what, S32 wher) | 1404 | void LLLineEditor::insert(std::string what, S32 wher) |
1319 | { | 1405 | { |
1320 | LLLineEditorRollback rollback(this); | 1406 | LLLineEditorRollback rollback(this); |
@@ -1925,7 +2011,7 @@ void LLLineEditor::drawMisspelled(LLRect background) | |||
1925 | } | 2011 | } |
1926 | } | 2012 | } |
1927 | 2013 | ||
1928 | if (mShowMisspellings) | 2014 | if (glggHunSpell->getSpellCheckHighlight()) |
1929 | { | 2015 | { |
1930 | for (int i =0; i<(int)misspellLocations.size(); i++) | 2016 | for (int i =0; i<(int)misspellLocations.size(); i++) |
1931 | { | 2017 | { |
@@ -2830,6 +2916,11 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory | |||
2830 | { | 2916 | { |
2831 | line_editor->setSpellCheckable(spell_checking); | 2917 | line_editor->setSpellCheckable(spell_checking); |
2832 | } | 2918 | } |
2919 | BOOL allow_translate = TRUE; | ||
2920 | if (node->getAttributeBOOL("allow_translate", allow_translate)) | ||
2921 | { | ||
2922 | line_editor->setAllowTranslate(allow_translate); | ||
2923 | } | ||
2833 | 2924 | ||
2834 | line_editor->setColorParameters(node); | 2925 | line_editor->setColorParameters(node); |
2835 | 2926 | ||
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index 147b232..f9e0621 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h | |||
@@ -107,6 +107,8 @@ public: | |||
107 | }; | 107 | }; |
108 | 108 | ||
109 | virtual void spellReplace(SpellMenuBind* spellData); | 109 | virtual void spellReplace(SpellMenuBind* spellData); |
110 | virtual void translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length); | ||
111 | virtual BOOL canTranslate() const; | ||
110 | virtual void insert(std::string what,S32 wher); | 112 | virtual void insert(std::string what,S32 wher); |
111 | 113 | ||
112 | // LLEditMenuHandler overrides | 114 | // LLEditMenuHandler overrides |
@@ -133,15 +135,22 @@ public: | |||
133 | virtual void deselect(); | 135 | virtual void deselect(); |
134 | virtual BOOL canDeselect() const; | 136 | virtual BOOL canDeselect() const; |
135 | 137 | ||
138 | static BOOL context_enable_cut(void* data); | ||
136 | static void context_cut(void* data); | 139 | static void context_cut(void* data); |
140 | static BOOL context_enable_copy(void* data); | ||
137 | static void context_copy(void* data); | 141 | static void context_copy(void* data); |
138 | static void spell_correct(void* data); | 142 | static BOOL context_enable_paste(void* data); |
139 | static void spell_show(void* data); | ||
140 | static void translateText(void * data); | ||
141 | static void spell_add(void* data); | ||
142 | static void context_paste(void* data); | 143 | static void context_paste(void* data); |
144 | static BOOL context_enable_delete(void* data); | ||
143 | static void context_delete(void* data); | 145 | static void context_delete(void* data); |
146 | static BOOL context_enable_selectall(void* data); | ||
144 | static void context_selectall(void* data); | 147 | static void context_selectall(void* data); |
148 | static BOOL context_enable_translate(void * data); | ||
149 | static void context_translate(void * data); | ||
150 | static void spell_correct(void* data); | ||
151 | static void spell_show(void* data); | ||
152 | static void spell_add(void* data); | ||
153 | |||
145 | std::vector<S32> getMisspelledWordsPositions(); | 154 | std::vector<S32> getMisspelledWordsPositions(); |
146 | // view overrides | 155 | // view overrides |
147 | virtual void draw(); | 156 | virtual void draw(); |
@@ -199,6 +208,7 @@ public: | |||
199 | void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } | 208 | void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } |
200 | void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; } | 209 | void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; } |
201 | void setSpellCheckable(BOOL b) { mSpellCheckable = b; } | 210 | void setSpellCheckable(BOOL b) { mSpellCheckable = b; } |
211 | void setAllowTranslate(BOOL b) { mAllowTranslate = b; } | ||
202 | 212 | ||
203 | const LLColor4& getFgColor() const { return mFgColor; } | 213 | const LLColor4& getFgColor() const { return mFgColor; } |
204 | const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor; } | 214 | const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor; } |
@@ -215,6 +225,7 @@ public: | |||
215 | // get the cursor position of the beginning/end of the prev/next word in the text | 225 | // get the cursor position of the beginning/end of the prev/next word in the text |
216 | S32 prevWordPos(S32 cursorPos) const; | 226 | S32 prevWordPos(S32 cursorPos) const; |
217 | S32 nextWordPos(S32 cursorPos) const; | 227 | S32 nextWordPos(S32 cursorPos) const; |
228 | BOOL getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const; | ||
218 | 229 | ||
219 | BOOL hasSelection() const { return (mSelectionStart != mSelectionEnd); } | 230 | BOOL hasSelection() const { return (mSelectionStart != mSelectionEnd); } |
220 | void startSelection(); | 231 | void startSelection(); |
@@ -261,7 +272,7 @@ private: | |||
261 | void removeChar(); | 272 | void removeChar(); |
262 | void addChar(const llwchar c); | 273 | void addChar(const llwchar c); |
263 | void setCursorAtLocalPos(S32 local_mouse_x); | 274 | void setCursorAtLocalPos(S32 local_mouse_x); |
264 | S32 calculateCursorFromMouse(S32 local_mouse_x); | 275 | S32 calculateCursorFromMouse(S32 local_mouse_x) const; |
265 | S32 findPixelNearestPos(S32 cursor_offset = 0) const; | 276 | S32 findPixelNearestPos(S32 cursor_offset = 0) const; |
266 | void reportBadKeystroke(); | 277 | void reportBadKeystroke(); |
267 | BOOL handleSpecialKey(KEY key, MASK mask); | 278 | BOOL handleSpecialKey(KEY key, MASK mask); |
@@ -294,10 +305,11 @@ protected: | |||
294 | S32 mStartSpellHere; // the position of the first char on the screen, stored so we know when to update | 305 | S32 mStartSpellHere; // the position of the first char on the screen, stored so we know when to update |
295 | S32 mEndSpellHere; // the location of the last char on the screen | 306 | S32 mEndSpellHere; // the location of the last char on the screen |
296 | BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field | 307 | BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field |
297 | BOOL mShowMisspellings; // show misspellings as highlighted (initialized in the ctor) | ||
298 | LLFrameTimer mSpellTimer; | 308 | LLFrameTimer mSpellTimer; |
299 | //to keep track of what we have to remove before showing menu | 309 | //to keep track of what we have to remove before showing menu |
300 | std::vector<SpellMenuBind* > suggestionMenuItems; | 310 | std::vector<SpellMenuBind* > suggestionMenuItems; |
311 | S32 mLastContextMenuX; | ||
312 | BOOL mAllowTranslate; // set in xui as "allow_translate". | ||
301 | 313 | ||
302 | // line history support: | 314 | // line history support: |
303 | BOOL mHaveHistory; // flag for enabled line history | 315 | BOOL mHaveHistory; // flag for enabled line history |
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index b101588..8dcb014 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp | |||
@@ -105,21 +105,23 @@ bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = | |||
105 | class TextChatTranslationReceiver : public LLTranslate::TranslationReceiver | 105 | class TextChatTranslationReceiver : public LLTranslate::TranslationReceiver |
106 | { | 106 | { |
107 | public : | 107 | public : |
108 | TextChatTranslationReceiver(const std::string &toLang, LLTextEditor* line): LLTranslate::TranslationReceiver("", toLang), | 108 | TextChatTranslationReceiver(const std::string &toLang, LLTextEditor* line, const S32 start, const S32 len): |
109 | m_line(line) | 109 | LLTranslate::TranslationReceiver("", toLang), |
110 | m_line(line), | ||
111 | m_position(start), | ||
112 | m_origLength(len) | ||
110 | { | 113 | { |
111 | } | 114 | } |
112 | 115 | ||
113 | static boost::intrusive_ptr<TextChatTranslationReceiver> build(const std::string &toLang,LLTextEditor* line) | 116 | static boost::intrusive_ptr<TextChatTranslationReceiver> build(const std::string &toLang,LLTextEditor* line, const S32 start, const S32 len) |
114 | { | 117 | { |
115 | return boost::intrusive_ptr<TextChatTranslationReceiver>(new TextChatTranslationReceiver(toLang,line)); | 118 | return boost::intrusive_ptr<TextChatTranslationReceiver>(new TextChatTranslationReceiver(toLang, line, start, len)); |
116 | } | 119 | } |
117 | 120 | ||
118 | protected: | 121 | protected: |
119 | void handleResponse(const std::string &translation, const std::string &detectedLanguage) | 122 | void handleResponse(const std::string &translation, const std::string &detectedLanguage) |
120 | { | 123 | { |
121 | BOOL rep = gSavedSettings.getBOOL("EmeraldTranslateReplace"); | 124 | m_line->translationReplace(translation, m_position, m_origLength); |
122 | m_line->insertText((rep?"":" (") + translation +(rep?"":")"),rep); | ||
123 | } | 125 | } |
124 | void handleFailure() | 126 | void handleFailure() |
125 | { | 127 | { |
@@ -127,6 +129,8 @@ protected: | |||
127 | } | 129 | } |
128 | private: | 130 | private: |
129 | LLTextEditor* m_line; | 131 | LLTextEditor* m_line; |
132 | S32 m_position; | ||
133 | S32 m_origLength; | ||
130 | }; | 134 | }; |
131 | 135 | ||
132 | /////////////////////////////////////////////////////////////////// | 136 | /////////////////////////////////////////////////////////////////// |
@@ -321,10 +325,12 @@ LLTextEditor::LLTextEditor( | |||
321 | mMouseDownY(0), | 325 | mMouseDownY(0), |
322 | mLastSelectionX(-1), | 326 | mLastSelectionX(-1), |
323 | mLastSelectionY(-1), | 327 | mLastSelectionY(-1), |
328 | mLastContextMenuX(-1), | ||
329 | mLastContextMenuY(-1), | ||
324 | mReflowNeeded(FALSE), | 330 | mReflowNeeded(FALSE), |
325 | mScrollNeeded(FALSE), | 331 | mScrollNeeded(FALSE), |
326 | mSpellCheckable(FALSE), | 332 | mSpellCheckable(FALSE), |
327 | mShowMisspellings(FALSE) | 333 | mAllowTranslate(TRUE) |
328 | { | 334 | { |
329 | mSourceID.generate(); | 335 | mSourceID.generate(); |
330 | 336 | ||
@@ -377,12 +383,6 @@ LLTextEditor::LLTextEditor( | |||
377 | mParseHTML=FALSE; | 383 | mParseHTML=FALSE; |
378 | mHTML.clear(); | 384 | mHTML.clear(); |
379 | 385 | ||
380 | // in other words, highlighting requires a restart | ||
381 | if (glggHunSpell->getSpellCheckHighlight()) | ||
382 | { | ||
383 | mShowMisspellings = TRUE; | ||
384 | } | ||
385 | |||
386 | // make the popup menu available | 386 | // make the popup menu available |
387 | //LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view); | 387 | //LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view); |
388 | LLMenuGL* menu = new LLMenuGL("wot"); | 388 | LLMenuGL* menu = new LLMenuGL("wot"); |
@@ -390,46 +390,46 @@ LLTextEditor::LLTextEditor( | |||
390 | { | 390 | { |
391 | menu = new LLMenuGL(LLStringUtil::null); | 391 | menu = new LLMenuGL(LLStringUtil::null); |
392 | }*/ | 392 | }*/ |
393 | menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this)); | 393 | menu->append(new LLMenuItemCallGL("Cut", context_cut, context_enable_cut, this)); |
394 | menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this)); | 394 | menu->append(new LLMenuItemCallGL("Copy", context_copy, context_enable_copy, this)); |
395 | menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this)); | 395 | menu->append(new LLMenuItemCallGL("Paste", context_paste, context_enable_paste, this)); |
396 | menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this)); | 396 | menu->append(new LLMenuItemCallGL("Delete", context_delete, context_enable_delete, this)); |
397 | menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this)); | 397 | menu->append(new LLMenuItemCallGL("Select All", context_selectall, context_enable_selectall, this)); |
398 | menu->appendSeparator("transep"); | 398 | menu->appendSeparator("Transep"); |
399 | LLMenuGL* translatemenu = new LLMenuGL("Translate To"); | 399 | LLMenuGL* translatemenu = new LLMenuGL("Translate To"); |
400 | translatemenu->setCanTearOff(FALSE); | 400 | translatemenu->setCanTearOff(FALSE); |
401 | SpellMenuBind* t=new SpellMenuBind;t->origin=this;t->word="en"; | 401 | SpellMenuBind* t=new SpellMenuBind;t->origin=this;t->word="en"; |
402 | translatemenu->append(new LLMenuItemCallGL("English",translateText, NULL, t)); | 402 | translatemenu->append(new LLMenuItemCallGL("English", context_translate, context_enable_translate, t)); |
403 | t=new SpellMenuBind;t->origin=this;t->word="da"; | 403 | t=new SpellMenuBind;t->origin=this;t->word="da"; |
404 | translatemenu->append(new LLMenuItemCallGL("Danish",translateText, NULL, t)); | 404 | translatemenu->append(new LLMenuItemCallGL("Danish", context_translate, context_enable_translate, t)); |
405 | t=new SpellMenuBind;t->origin=this;t->word="de"; | 405 | t=new SpellMenuBind;t->origin=this;t->word="de"; |
406 | translatemenu->append(new LLMenuItemCallGL("Deutsch(German)",translateText, NULL, t)); | 406 | translatemenu->append(new LLMenuItemCallGL("Deutsch(German)", context_translate, context_enable_translate, t)); |
407 | t=new SpellMenuBind;t->origin=this;t->word="es"; | 407 | t=new SpellMenuBind;t->origin=this;t->word="es"; |
408 | translatemenu->append(new LLMenuItemCallGL("Spanish",translateText, NULL, t)); | 408 | translatemenu->append(new LLMenuItemCallGL("Spanish", context_translate, context_enable_translate, t)); |
409 | t=new SpellMenuBind;t->origin=this;t->word="fr"; | 409 | t=new SpellMenuBind;t->origin=this;t->word="fr"; |
410 | translatemenu->append(new LLMenuItemCallGL("French",translateText, NULL, t)); | 410 | translatemenu->append(new LLMenuItemCallGL("French", context_translate, context_enable_translate, t)); |
411 | t=new SpellMenuBind;t->origin=this;t->word="it"; | 411 | t=new SpellMenuBind;t->origin=this;t->word="it"; |
412 | translatemenu->append(new LLMenuItemCallGL("Italian",translateText, NULL, t)); | 412 | translatemenu->append(new LLMenuItemCallGL("Italian", context_translate, context_enable_translate, t)); |
413 | t=new SpellMenuBind;t->origin=this;t->word="hu"; | 413 | t=new SpellMenuBind;t->origin=this;t->word="hu"; |
414 | translatemenu->append(new LLMenuItemCallGL("Hungarian",translateText, NULL, t)); | 414 | translatemenu->append(new LLMenuItemCallGL("Hungarian", context_translate, context_enable_translate, t)); |
415 | t=new SpellMenuBind;t->origin=this;t->word="nl"; | 415 | t=new SpellMenuBind;t->origin=this;t->word="nl"; |
416 | translatemenu->append(new LLMenuItemCallGL("Dutch",translateText, NULL, t)); | 416 | translatemenu->append(new LLMenuItemCallGL("Dutch", context_translate, context_enable_translate, t)); |
417 | t=new SpellMenuBind;t->origin=this;t->word="pl"; | 417 | t=new SpellMenuBind;t->origin=this;t->word="pl"; |
418 | translatemenu->append(new LLMenuItemCallGL("Polish",translateText, NULL, t)); | 418 | translatemenu->append(new LLMenuItemCallGL("Polish", context_translate, context_enable_translate, t)); |
419 | t=new SpellMenuBind;t->origin=this;t->word="pt"; | 419 | t=new SpellMenuBind;t->origin=this;t->word="pt"; |
420 | translatemenu->append(new LLMenuItemCallGL("Portugese",translateText, NULL, t)); | 420 | translatemenu->append(new LLMenuItemCallGL("Portugese", context_translate, context_enable_translate, t)); |
421 | t=new SpellMenuBind;t->origin=this;t->word="ru"; | 421 | t=new SpellMenuBind;t->origin=this;t->word="ru"; |
422 | translatemenu->append(new LLMenuItemCallGL("Russian",translateText, NULL, t)); | 422 | translatemenu->append(new LLMenuItemCallGL("Russian", context_translate, context_enable_translate, t)); |
423 | t=new SpellMenuBind;t->origin=this;t->word="tr"; | 423 | t=new SpellMenuBind;t->origin=this;t->word="tr"; |
424 | translatemenu->append(new LLMenuItemCallGL("Turkish",translateText, NULL, t)); | 424 | translatemenu->append(new LLMenuItemCallGL("Turkish", context_translate, context_enable_translate, t)); |
425 | t=new SpellMenuBind;t->origin=this;t->word="uk"; | 425 | t=new SpellMenuBind;t->origin=this;t->word="uk"; |
426 | translatemenu->append(new LLMenuItemCallGL("Ukrainian",translateText, NULL, t)); | 426 | translatemenu->append(new LLMenuItemCallGL("Ukrainian", context_translate, context_enable_translate, t)); |
427 | t=new SpellMenuBind;t->origin=this;t->word="zh"; | 427 | t=new SpellMenuBind;t->origin=this;t->word="zh"; |
428 | translatemenu->append(new LLMenuItemCallGL("Chinese",translateText, NULL, t)); | 428 | translatemenu->append(new LLMenuItemCallGL("Chinese", context_translate, context_enable_translate, t)); |
429 | t=new SpellMenuBind;t->origin=this;t->word="ja"; | 429 | t=new SpellMenuBind;t->origin=this;t->word="ja"; |
430 | translatemenu->append(new LLMenuItemCallGL("Japanese",translateText, NULL, t)); | 430 | translatemenu->append(new LLMenuItemCallGL("Japanese", context_translate, context_enable_translate, t)); |
431 | t=new SpellMenuBind;t->origin=this;t->word="ko"; | 431 | t=new SpellMenuBind;t->origin=this;t->word="ko"; |
432 | translatemenu->append(new LLMenuItemCallGL("Korean",translateText, NULL, t)); | 432 | translatemenu->append(new LLMenuItemCallGL("Korean", context_translate, context_enable_translate, t)); |
433 | 433 | ||
434 | menu->appendMenu(translatemenu); | 434 | menu->appendMenu(translatemenu); |
435 | menu->appendSeparator("Spelsep"); | 435 | menu->appendSeparator("Spelsep"); |
@@ -439,7 +439,6 @@ LLTextEditor::LLTextEditor( | |||
439 | mPopupMenuHandle = menu->getHandle(); | 439 | mPopupMenuHandle = menu->getHandle(); |
440 | } | 440 | } |
441 | 441 | ||
442 | |||
443 | LLTextEditor::~LLTextEditor() | 442 | LLTextEditor::~LLTextEditor() |
444 | { | 443 | { |
445 | gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() | 444 | gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() |
@@ -457,27 +456,67 @@ LLTextEditor::~LLTextEditor() | |||
457 | std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); | 456 | std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); |
458 | LLView::deleteViewByHandle(mPopupMenuHandle); | 457 | LLView::deleteViewByHandle(mPopupMenuHandle); |
459 | } | 458 | } |
459 | |||
460 | BOOL LLTextEditor::context_enable_cut(void* data) | ||
461 | { | ||
462 | LLTextEditor* line = (LLTextEditor*)data; | ||
463 | return (line && line->canCut()); | ||
464 | } | ||
465 | |||
460 | void LLTextEditor::context_cut(void* data) | 466 | void LLTextEditor::context_cut(void* data) |
461 | { | 467 | { |
462 | LLTextEditor* line = (LLTextEditor*)data; | 468 | LLTextEditor* line = (LLTextEditor*)data; |
463 | if(line)line->cut(); | 469 | if(line)line->cut(); |
464 | } | 470 | } |
471 | |||
472 | BOOL LLTextEditor::context_enable_copy(void* data) | ||
473 | { | ||
474 | LLTextEditor* line = (LLTextEditor*)data; | ||
475 | return (line && line->canCopy()); | ||
476 | } | ||
477 | |||
465 | void LLTextEditor::context_copy(void* data) | 478 | void LLTextEditor::context_copy(void* data) |
466 | { | 479 | { |
467 | LLTextEditor* line = (LLTextEditor*)data; | 480 | LLTextEditor* line = (LLTextEditor*)data; |
468 | if(line)line->copy(); | 481 | if(line)line->copy(); |
469 | } | 482 | } |
470 | void LLTextEditor::translateText(void * data) | 483 | |
484 | BOOL LLTextEditor::context_enable_translate(void * data) | ||
485 | { | ||
486 | SpellMenuBind* t = (SpellMenuBind*)data; | ||
487 | return (t && t->origin && t->origin->canTranslate()); | ||
488 | } | ||
489 | |||
490 | void LLTextEditor::context_translate(void * data) | ||
471 | { | 491 | { |
472 | SpellMenuBind* t = (SpellMenuBind*)data; | 492 | SpellMenuBind* t = (SpellMenuBind*)data; |
473 | LLTextEditor* line = t->origin; | 493 | LLTextEditor* line = t->origin; |
474 | const std::string &toLang = t->word;//LLTranslate::getTranslateLanguage(); | 494 | const std::string &toLang = t->word;//LLTranslate::getTranslateLanguage(); |
475 | LLHTTPClient::ResponderPtr result = TextChatTranslationReceiver::build(toLang,line); | ||
476 | 495 | ||
477 | S32 left_pos = llmin( line->mSelectionStart, line->mSelectionEnd ); | 496 | bool has_text = false; |
478 | S32 length = abs( line->mSelectionStart - line->mSelectionEnd ); | 497 | S32 start, length; |
479 | LLTranslate::translateMessage(result,"", toLang, line->getText().substr(left_pos, length)); | 498 | if (line->hasSelection()) |
499 | { | ||
500 | // translate selection | ||
501 | start = llmin(line->mSelectionStart, line->mSelectionEnd); | ||
502 | length = abs(line->mSelectionEnd - line->mSelectionStart); | ||
503 | has_text = length > 0; | ||
504 | } | ||
505 | else | ||
506 | { | ||
507 | // translate one word as click position | ||
508 | S32 at = line->getCursorPosFromLocalCoord(line->mLastContextMenuX, line->mLastContextMenuY, TRUE); | ||
509 | has_text = line->getWordBoundriesAt(at, &start, &length); | ||
510 | } | ||
511 | |||
512 | if (has_text) | ||
513 | { | ||
514 | const std::string to_translate = wstring_to_utf8str(line->getWText().substr(start, length)); | ||
515 | LLHTTPClient::ResponderPtr result = TextChatTranslationReceiver::build(toLang, line, start, length); | ||
516 | LLTranslate::translateMessage(result,"", toLang, to_translate); | ||
517 | } | ||
480 | } | 518 | } |
519 | |||
481 | void LLTextEditor::spell_correct(void* data) | 520 | void LLTextEditor::spell_correct(void* data) |
482 | { | 521 | { |
483 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | 522 | SpellMenuBind* tempBind = (SpellMenuBind*)data; |
@@ -496,14 +535,8 @@ void LLTextEditor::spell_show(void * data) | |||
496 | 535 | ||
497 | if (tempBind && line) | 536 | if (tempBind && line) |
498 | { | 537 | { |
499 | if (tempBind->word == "Show Misspellings") | 538 | BOOL show = (tempBind->word == "Show Misspellings"); |
500 | { | 539 | glggHunSpell->setSpellCheckHighlight(show); |
501 | glggHunSpell->setSpellCheckHighlight(TRUE); | ||
502 | } | ||
503 | else | ||
504 | { | ||
505 | glggHunSpell->setSpellCheckHighlight(FALSE); | ||
506 | } | ||
507 | } | 540 | } |
508 | } | 541 | } |
509 | 542 | ||
@@ -555,16 +588,37 @@ void LLTextEditor::spell_add(void* data) | |||
555 | tempBind->origin->mPrevSpelledText.erase();//make it update | 588 | tempBind->origin->mPrevSpelledText.erase();//make it update |
556 | } | 589 | } |
557 | } | 590 | } |
591 | |||
592 | BOOL LLTextEditor::context_enable_paste(void* data) | ||
593 | { | ||
594 | LLTextEditor* line = (LLTextEditor*)data; | ||
595 | return(line && line->canPaste()); | ||
596 | } | ||
597 | |||
558 | void LLTextEditor::context_paste(void* data) | 598 | void LLTextEditor::context_paste(void* data) |
559 | { | 599 | { |
560 | LLTextEditor* line = (LLTextEditor*)data; | 600 | LLTextEditor* line = (LLTextEditor*)data; |
561 | if(line)line->paste(); | 601 | if(line)line->paste(); |
562 | } | 602 | } |
603 | |||
604 | BOOL LLTextEditor::context_enable_delete(void* data) | ||
605 | { | ||
606 | LLTextEditor* line = (LLTextEditor*)data; | ||
607 | return (line && line->canDoDelete()); | ||
608 | } | ||
609 | |||
563 | void LLTextEditor::context_delete(void* data) | 610 | void LLTextEditor::context_delete(void* data) |
564 | { | 611 | { |
565 | LLTextEditor* line = (LLTextEditor*)data; | 612 | LLTextEditor* line = (LLTextEditor*)data; |
566 | if(line)line->doDelete(); | 613 | if(line)line->doDelete(); |
567 | } | 614 | } |
615 | |||
616 | BOOL LLTextEditor::context_enable_selectall(void* data) | ||
617 | { | ||
618 | LLTextEditor* line = (LLTextEditor*)data; | ||
619 | return (line && line->canSelectAll()); | ||
620 | } | ||
621 | |||
568 | void LLTextEditor::context_selectall(void* data) | 622 | void LLTextEditor::context_selectall(void* data) |
569 | { | 623 | { |
570 | LLTextEditor* line = (LLTextEditor*)data; | 624 | LLTextEditor* line = (LLTextEditor*)data; |
@@ -947,6 +1001,26 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const | |||
947 | return cursorPos; | 1001 | return cursorPos; |
948 | } | 1002 | } |
949 | 1003 | ||
1004 | BOOL LLTextEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const | ||
1005 | { | ||
1006 | S32 pos = at; | ||
1007 | if (isPartOfWord(mWText[pos])) | ||
1008 | { | ||
1009 | while ( (pos > 0) && isPartOfWord(mWText[pos - 1]) ) | ||
1010 | { | ||
1011 | pos--; | ||
1012 | } | ||
1013 | *word_begin = pos; | ||
1014 | while ( (pos < getLength()) && isPartOfWord(mWText[pos]) ) | ||
1015 | { | ||
1016 | pos++; | ||
1017 | } | ||
1018 | *word_length = pos - *word_begin; | ||
1019 | return TRUE; | ||
1020 | } | ||
1021 | return FALSE; | ||
1022 | } | ||
1023 | |||
950 | S32 LLTextEditor::getLineStart( S32 line ) const | 1024 | S32 LLTextEditor::getLineStart( S32 line ) const |
951 | { | 1025 | { |
952 | S32 num_lines = getLineCount(); | 1026 | S32 num_lines = getLineCount(); |
@@ -1439,7 +1513,8 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1439 | 1513 | ||
1440 | //setCursorAtLocalPos( x, y, TRUE ); | 1514 | //setCursorAtLocalPos( x, y, TRUE ); |
1441 | S32 wordStart = 0; | 1515 | S32 wordStart = 0; |
1442 | S32 wordEnd = getCursorPosFromLocalCoord(x,y,TRUE); | 1516 | S32 wordEnd = 0; |
1517 | S32 pos = getCursorPosFromLocalCoord(x,y,TRUE); | ||
1443 | 1518 | ||
1444 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | 1519 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); |
1445 | if (menu) | 1520 | if (menu) |
@@ -1458,35 +1533,21 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1458 | } | 1533 | } |
1459 | suggestionMenuItems.clear(); | 1534 | suggestionMenuItems.clear(); |
1460 | 1535 | ||
1461 | menu->setItemVisible("Translate To", !mReadOnly); | ||
1462 | menu->setItemVisible("Transep", !mReadOnly); | ||
1463 | |||
1464 | // spell_check="true" in xui | 1536 | // spell_check="true" in xui |
1537 | menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable); | ||
1465 | if (!mReadOnly && mSpellCheckable) | 1538 | if (!mReadOnly && mSpellCheckable) |
1466 | { | 1539 | { |
1467 | const LLWString &text = mWText; | 1540 | bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordEnd); |
1468 | 1541 | if (is_word_part) | |
1469 | if (isPartOfWord(text[wordEnd]) && !mReadOnly) | ||
1470 | { | 1542 | { |
1471 | // Select word the cursor is over | 1543 | const LLWString &text = mWText; |
1472 | while ((wordEnd > 0) && isPartOfWord(text[wordEnd-1])) | ||
1473 | { | ||
1474 | wordEnd--; | ||
1475 | } | ||
1476 | wordStart = wordEnd; | ||
1477 | //startSelection(); | ||
1478 | |||
1479 | while ((wordEnd < (S32)text.length()) && isPartOfWord( text[wordEnd] ) ) | ||
1480 | { | ||
1481 | wordEnd++; | ||
1482 | } | ||
1483 | std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart)); | 1544 | std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart)); |
1545 | |||
1484 | if (!glggHunSpell->isSpelledRight(selectedWord)) | 1546 | if (!glggHunSpell->isSpelledRight(selectedWord)) |
1485 | { | 1547 | { |
1486 | //misspelled word here, and you have just right clicked on it! | 1548 | //misspelled word here, and you have just right clicked on it! |
1487 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); | 1549 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); |
1488 | 1550 | ||
1489 | //menu->setItemVisible("Transep",(suggs.size()>0)); | ||
1490 | for (int i = 0; i<(int)suggs.size(); i++) | 1551 | for (int i = 0; i<(int)suggs.size(); i++) |
1491 | { | 1552 | { |
1492 | SpellMenuBind * tempStruct = new SpellMenuBind; | 1553 | SpellMenuBind * tempStruct = new SpellMenuBind; |
@@ -1517,7 +1578,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1517 | 1578 | ||
1518 | SpellMenuBind * tempStruct = new SpellMenuBind; | 1579 | SpellMenuBind * tempStruct = new SpellMenuBind; |
1519 | tempStruct->origin = this; | 1580 | tempStruct->origin = this; |
1520 | if (mShowMisspellings) | 1581 | if (glggHunSpell->getSpellCheckHighlight()) |
1521 | { | 1582 | { |
1522 | tempStruct->word = "Hide Misspellings"; | 1583 | tempStruct->word = "Hide Misspellings"; |
1523 | } | 1584 | } |
@@ -1531,6 +1592,8 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1531 | suggestionMenuItems.push_back(tempStruct); | 1592 | suggestionMenuItems.push_back(tempStruct); |
1532 | menu->append(suggMenuItem); | 1593 | menu->append(suggMenuItem); |
1533 | } | 1594 | } |
1595 | mLastContextMenuX = x; | ||
1596 | mLastContextMenuY = y; | ||
1534 | menu->buildDrawLabels(); | 1597 | menu->buildDrawLabels(); |
1535 | menu->updateParent(LLMenuGL::sMenuContainer); | 1598 | menu->updateParent(LLMenuGL::sMenuContainer); |
1536 | LLMenuGL::showPopup(this, menu, x, y); | 1599 | LLMenuGL::showPopup(this, menu, x, y); |
@@ -2238,6 +2301,35 @@ void LLTextEditor::spellReplace(SpellMenuBind* spellData) | |||
2238 | needsReflow(); | 2301 | needsReflow(); |
2239 | } | 2302 | } |
2240 | 2303 | ||
2304 | void LLTextEditor::translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length) | ||
2305 | { | ||
2306 | //*TODO: should probably check if the content was modified since the http query | ||
2307 | // was made, so we don't insert text in the wrong place. | ||
2308 | BOOL replace = gSavedSettings.getBOOL("EmeraldTranslateReplace"); | ||
2309 | LLWString wtext = utf8str_to_wstring(replace ? translation : " (" + translation + ")"); | ||
2310 | S32 pos = replace ? orig_start : orig_start + orig_length; | ||
2311 | if (replace) | ||
2312 | { | ||
2313 | remove(orig_start, orig_length, FALSE); | ||
2314 | } | ||
2315 | S32 inserted = insert(pos, wtext, FALSE); | ||
2316 | if (hasSelection()) | ||
2317 | { | ||
2318 | mSelectionStart = llclamp(pos, 0, getLength()); | ||
2319 | mSelectionEnd = llclamp(pos + inserted, mSelectionStart, getLength()); | ||
2320 | } | ||
2321 | setCursorPos(pos + inserted); | ||
2322 | needsReflow(); | ||
2323 | } | ||
2324 | |||
2325 | BOOL LLTextEditor::canTranslate() const | ||
2326 | { | ||
2327 | // if allow_translate="true" in xui, and if other factors permit, we allow it | ||
2328 | S32 pos = getCursorPosFromLocalCoord(mLastContextMenuX, mLastContextMenuY, TRUE); | ||
2329 | bool is_word_part = (pos > -1) && isPartOfWord(mWText[pos]); | ||
2330 | return (mAllowTranslate && !mReadOnly && (is_word_part || hasSelection())); | ||
2331 | } | ||
2332 | |||
2241 | // paste from clipboard | 2333 | // paste from clipboard |
2242 | void LLTextEditor::paste() | 2334 | void LLTextEditor::paste() |
2243 | { | 2335 | { |
@@ -3162,7 +3254,7 @@ void LLTextEditor::drawMisspelled() | |||
3162 | } | 3254 | } |
3163 | } | 3255 | } |
3164 | //draw | 3256 | //draw |
3165 | if (mShowMisspellings) | 3257 | if (glggHunSpell->getSpellCheckHighlight()) |
3166 | { | 3258 | { |
3167 | for (int i = 0; i<(int)misspellLocations.size() ;i++) | 3259 | for (int i = 0; i<(int)misspellLocations.size() ;i++) |
3168 | { | 3260 | { |
@@ -4901,6 +4993,8 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node) | |||
4901 | 4993 | ||
4902 | node->getAttributeBOOL("spell_check", mSpellCheckable); | 4994 | node->getAttributeBOOL("spell_check", mSpellCheckable); |
4903 | 4995 | ||
4996 | node->getAttributeBOOL("allow_translate", mAllowTranslate); | ||
4997 | |||
4904 | LLColor4 color; | 4998 | LLColor4 color; |
4905 | if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) | 4999 | if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) |
4906 | { | 5000 | { |
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index 57a6bbd..f2a831b 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h | |||
@@ -136,6 +136,8 @@ public: | |||
136 | virtual BOOL canPaste() const; | 136 | virtual BOOL canPaste() const; |
137 | 137 | ||
138 | virtual void spellReplace(SpellMenuBind* spellData); | 138 | virtual void spellReplace(SpellMenuBind* spellData); |
139 | virtual void translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length); | ||
140 | virtual BOOL canTranslate() const; | ||
139 | 141 | ||
140 | virtual void updatePrimary(); | 142 | virtual void updatePrimary(); |
141 | virtual void copyPrimary(); | 143 | virtual void copyPrimary(); |
@@ -148,13 +150,19 @@ public: | |||
148 | virtual BOOL canSelectAll() const; | 150 | virtual BOOL canSelectAll() const; |
149 | virtual void deselect(); | 151 | virtual void deselect(); |
150 | virtual BOOL canDeselect() const; | 152 | virtual BOOL canDeselect() const; |
151 | static void context_cut(void* data); | ||
152 | 153 | ||
154 | static BOOL context_enable_cut(void* data); | ||
155 | static void context_cut(void* data); | ||
156 | static BOOL context_enable_copy(void* data); | ||
153 | static void context_copy(void* data); | 157 | static void context_copy(void* data); |
158 | static BOOL context_enable_paste(void* data); | ||
154 | static void context_paste(void* data); | 159 | static void context_paste(void* data); |
160 | static BOOL context_enable_delete(void* data); | ||
155 | static void context_delete(void* data); | 161 | static void context_delete(void* data); |
162 | static BOOL context_enable_selectall(void* data); | ||
156 | static void context_selectall(void* data); | 163 | static void context_selectall(void* data); |
157 | static void translateText(void * data); | 164 | static BOOL context_enable_translate(void * data); |
165 | static void context_translate(void * data); | ||
158 | static void spell_correct(void* data); | 166 | static void spell_correct(void* data); |
159 | static void spell_add(void* data); | 167 | static void spell_add(void* data); |
160 | static void spell_show(void* data); | 168 | static void spell_show(void* data); |
@@ -352,6 +360,7 @@ public: | |||
352 | 360 | ||
353 | S32 prevWordPos(S32 cursorPos) const; | 361 | S32 prevWordPos(S32 cursorPos) const; |
354 | S32 nextWordPos(S32 cursorPos) const; | 362 | S32 nextWordPos(S32 cursorPos) const; |
363 | BOOL getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const; | ||
355 | 364 | ||
356 | S32 getLineCount() const { return mLineStartList.size(); } | 365 | S32 getLineCount() const { return mLineStartList.size(); } |
357 | S32 getLineStart( S32 line ) const; | 366 | S32 getLineStart( S32 line ) const; |
@@ -527,7 +536,7 @@ private: | |||
527 | S32 spellEnd; | 536 | S32 spellEnd; |
528 | std::vector<S32> misspellLocations; // where all the mispelled words are | 537 | std::vector<S32> misspellLocations; // where all the mispelled words are |
529 | BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field | 538 | BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field |
530 | BOOL mShowMisspellings; // show misspellings as highlighted (initialized in the ctor) | 539 | BOOL mAllowTranslate; // set in xui as "allow_translate". |
531 | 540 | ||
532 | S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes | 541 | S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes |
533 | 542 | ||
@@ -568,6 +577,8 @@ private: | |||
568 | 577 | ||
569 | //to keep track of what we have to remove before showing menu | 578 | //to keep track of what we have to remove before showing menu |
570 | std::vector<SpellMenuBind* > suggestionMenuItems; | 579 | std::vector<SpellMenuBind* > suggestionMenuItems; |
580 | S32 mLastContextMenuX; | ||
581 | S32 mLastContextMenuY; | ||
571 | 582 | ||
572 | line_list_t mLineStartList; | 583 | line_list_t mLineStartList; |
573 | BOOL mReflowNeeded; | 584 | BOOL mReflowNeeded; |
diff --git a/linden/indra/newview/lgghunspell_wrapper.cpp b/linden/indra/newview/lgghunspell_wrapper.cpp index f800043..aa4507c 100644 --- a/linden/indra/newview/lgghunspell_wrapper.cpp +++ b/linden/indra/newview/lgghunspell_wrapper.cpp | |||
@@ -72,7 +72,7 @@ static char * countryCodesraw[] = { | |||
72 | (char*)"CF",(char*)"Central African Republic", | 72 | (char*)"CF",(char*)"Central African Republic", |
73 | (char*)"CG",(char*)"Congo", | 73 | (char*)"CG",(char*)"Congo", |
74 | (char*)"CH",(char*)"Switzerland", | 74 | (char*)"CH",(char*)"Switzerland", |
75 | (char*)"CI",(char*)"Côte D'ivoire (Ivory Coast)", | 75 | (char*)"CI",(char*)"Côte D'ivoire (Ivory Coast)", |
76 | (char*)"CK",(char*)"Cook Iislands", | 76 | (char*)"CK",(char*)"Cook Iislands", |
77 | (char*)"CL",(char*)"Chile", | 77 | (char*)"CL",(char*)"Chile", |
78 | (char*)"CM",(char*)"Cameroon", | 78 | (char*)"CM",(char*)"Cameroon", |
@@ -212,7 +212,7 @@ static char * countryCodesraw[] = { | |||
212 | (char*)"PW",(char*)"Palau", | 212 | (char*)"PW",(char*)"Palau", |
213 | (char*)"PY",(char*)"Paraguay", | 213 | (char*)"PY",(char*)"Paraguay", |
214 | (char*)"QA",(char*)"Qatar", | 214 | (char*)"QA",(char*)"Qatar", |
215 | (char*)"RE",(char*)"Réunion", | 215 | (char*)"RE",(char*)"Réunion", |
216 | (char*)"RO",(char*)"Romania", | 216 | (char*)"RO",(char*)"Romania", |
217 | (char*)"RU",(char*)"Russian Federation", | 217 | (char*)"RU",(char*)"Russian Federation", |
218 | (char*)"RW",(char*)"Rwanda", | 218 | (char*)"RW",(char*)"Rwanda", |
@@ -333,7 +333,7 @@ static char * languageCodesraw[]={ | |||
333 | (char*)"ga",(char*)"Irish", | 333 | (char*)"ga",(char*)"Irish", |
334 | (char*)"gd",(char*)"Gaelic", | 334 | (char*)"gd",(char*)"Gaelic", |
335 | (char*)"gl",(char*)"Galician", | 335 | (char*)"gl",(char*)"Galician", |
336 | (char*)"gn",(char*)"Guaraní", | 336 | (char*)"gn",(char*)"GuaranÃ", |
337 | (char*)"gu",(char*)"Gujarati", | 337 | (char*)"gu",(char*)"Gujarati", |
338 | (char*)"gv",(char*)"Manx", | 338 | (char*)"gv",(char*)"Manx", |
339 | (char*)"ha",(char*)"Hausa", | 339 | (char*)"ha",(char*)"Hausa", |
@@ -456,7 +456,7 @@ static char * languageCodesraw[]={ | |||
456 | (char*)"uz",(char*)"Uzbek", | 456 | (char*)"uz",(char*)"Uzbek", |
457 | (char*)"ve",(char*)"Venda", | 457 | (char*)"ve",(char*)"Venda", |
458 | (char*)"vi",(char*)"Vietnamese", | 458 | (char*)"vi",(char*)"Vietnamese", |
459 | (char*)"vo",(char*)"Volapük", | 459 | (char*)"vo",(char*)"Volapük", |
460 | (char*)"wa",(char*)"Walloon", | 460 | (char*)"wa",(char*)"Walloon", |
461 | (char*)"wo",(char*)"Wolof", | 461 | (char*)"wo",(char*)"Wolof", |
462 | (char*)"xh",(char*)"Xhosa", | 462 | (char*)"xh",(char*)"Xhosa", |
@@ -470,10 +470,9 @@ static char * languageCodesraw[]={ | |||
470 | #define LANGUAGE_CODES_RAW_SIZE 368 | 470 | #define LANGUAGE_CODES_RAW_SIZE 368 |
471 | 471 | ||
472 | lggHunSpell_Wrapper::lggHunSpell_Wrapper() | 472 | lggHunSpell_Wrapper::lggHunSpell_Wrapper() |
473 | : | ||
474 | mSpellCheckHighlight(false) | ||
475 | { | 473 | { |
476 | //languageCodes(begin(languageCodesraw), end(languageCodesraw)); | 474 | //languageCodes(begin(languageCodesraw), end(languageCodesraw)); |
475 | mSpellCheckHighlight = rebind_llcontrol<BOOL>("EmeraldSpellDisplay", &gSavedSettings, false); | ||
477 | } | 476 | } |
478 | 477 | ||
479 | lggHunSpell_Wrapper::~lggHunSpell_Wrapper() | 478 | lggHunSpell_Wrapper::~lggHunSpell_Wrapper() |
@@ -638,8 +637,6 @@ void lggHunSpell_Wrapper::processSettings() | |||
638 | //expects everything to already be in saved settings | 637 | //expects everything to already be in saved settings |
639 | //this will also reload and read the installed dicts | 638 | //this will also reload and read the installed dicts |
640 | setNewDictionary(gSavedSettings.getString("EmeraldSpellBase")); | 639 | setNewDictionary(gSavedSettings.getString("EmeraldSpellBase")); |
641 | mSpellCheckHighlight = gSavedSettings.getBOOL("EmeraldSpellDisplay"); | ||
642 | |||
643 | } | 640 | } |
644 | 641 | ||
645 | void lggHunSpell_Wrapper::addDictionary(std::string additionalDictionary) | 642 | void lggHunSpell_Wrapper::addDictionary(std::string additionalDictionary) |
@@ -966,5 +963,8 @@ void lggHunSpell_Wrapper::editCustomButton() | |||
966 | 963 | ||
967 | void lggHunSpell_Wrapper::setSpellCheckHighlight(BOOL highlight) | 964 | void lggHunSpell_Wrapper::setSpellCheckHighlight(BOOL highlight) |
968 | { | 965 | { |
969 | mSpellCheckHighlight = highlight; | 966 | if (mSpellCheckHighlight) |
967 | { | ||
968 | *mSpellCheckHighlight = highlight; | ||
969 | } | ||
970 | } | 970 | } |
diff --git a/linden/indra/newview/lgghunspell_wrapper.h b/linden/indra/newview/lgghunspell_wrapper.h index b5f3ddb..71b2f14 100644 --- a/linden/indra/newview/lgghunspell_wrapper.h +++ b/linden/indra/newview/lgghunspell_wrapper.h | |||
@@ -55,7 +55,7 @@ public: | |||
55 | std::string VEC2CSV(std::vector<std::string> vec); | 55 | std::string VEC2CSV(std::vector<std::string> vec); |
56 | 56 | ||
57 | void setSpellCheckHighlight(BOOL highlight); | 57 | void setSpellCheckHighlight(BOOL highlight); |
58 | BOOL getSpellCheckHighlight() { return mSpellCheckHighlight; } | 58 | BOOL getSpellCheckHighlight() { return mSpellCheckHighlight && *mSpellCheckHighlight; } |
59 | 59 | ||
60 | private: | 60 | private: |
61 | void createCustomDic(); | 61 | void createCustomDic(); |
@@ -67,7 +67,7 @@ private: | |||
67 | std::string currentBaseDic; | 67 | std::string currentBaseDic; |
68 | //std::vector<std::string> languageCodes; | 68 | //std::vector<std::string> languageCodes; |
69 | //std::vector<std::string> countryCodes; | 69 | //std::vector<std::string> countryCodes; |
70 | BOOL mSpellCheckHighlight; | 70 | BOOL* mSpellCheckHighlight; |
71 | }; | 71 | }; |
72 | 72 | ||
73 | extern lggHunSpell_Wrapper* glggHunSpell; // the singleton hunspell wrapper | 73 | extern lggHunSpell_Wrapper* glggHunSpell; // the singleton hunspell wrapper |
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index 35fd395..6322d27 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp | |||
@@ -2716,43 +2716,46 @@ void process_decline_callingcard(LLMessageSystem* msg, void**) | |||
2716 | class ChatTranslationReceiver : public LLTranslate::TranslationReceiver | 2716 | class ChatTranslationReceiver : public LLTranslate::TranslationReceiver |
2717 | { | 2717 | { |
2718 | public : | 2718 | public : |
2719 | ChatTranslationReceiver(const std::string &fromLang, const std::string &toLang, LLChat *chat, | 2719 | ChatTranslationReceiver(const std::string &fromLang, const std::string &toLang, const LLChat &chat, |
2720 | const BOOL history) | 2720 | const std::string &orig_mesg, const BOOL history) |
2721 | : LLTranslate::TranslationReceiver(fromLang, toLang), | 2721 | : LLTranslate::TranslationReceiver(fromLang, toLang), |
2722 | m_chat(chat), | 2722 | m_chat(chat), |
2723 | m_origMesg(orig_mesg), | ||
2723 | m_history(history) | 2724 | m_history(history) |
2724 | { | 2725 | { |
2725 | } | 2726 | } |
2726 | 2727 | ||
2727 | static boost::intrusive_ptr<ChatTranslationReceiver> build(const std::string &fromLang, const std::string &toLang, LLChat *chat, const BOOL history) | 2728 | static boost::intrusive_ptr<ChatTranslationReceiver> build(const std::string &fromLang, const std::string &toLang, const LLChat &chat, const std::string &orig_mesg, const BOOL history) |
2728 | { | 2729 | { |
2729 | return boost::intrusive_ptr<ChatTranslationReceiver>(new ChatTranslationReceiver(fromLang, toLang, chat, history)); | 2730 | return boost::intrusive_ptr<ChatTranslationReceiver>(new ChatTranslationReceiver(fromLang, toLang, chat, orig_mesg, history)); |
2730 | } | 2731 | } |
2731 | 2732 | ||
2732 | protected: | 2733 | protected: |
2733 | void handleResponse(const std::string &translation, const std::string &detectedLanguage) | 2734 | void handleResponse(const std::string &translation, const std::string &detected_language) |
2734 | { | 2735 | { |
2735 | if (m_toLang != detectedLanguage) | 2736 | // filter out non-interesting responeses |
2736 | m_chat->mText += " (" + translation + ")"; | 2737 | if ( !translation.empty() |
2737 | 2738 | && (m_toLang != detected_language) | |
2738 | add_floater_chat(*m_chat, m_history); | 2739 | && (LLStringUtil::compareInsensitive(translation, m_origMesg) != 0) ) |
2740 | { | ||
2741 | m_chat.mText += " (" + translation + ")"; | ||
2742 | } | ||
2739 | 2743 | ||
2740 | delete m_chat; | 2744 | add_floater_chat(m_chat, m_history); |
2741 | } | 2745 | } |
2742 | 2746 | ||
2743 | void handleFailure() | 2747 | void handleFailure() |
2744 | { | 2748 | { |
2745 | LLTranslate::TranslationReceiver::handleFailure(); | 2749 | LLTranslate::TranslationReceiver::handleFailure(); |
2746 | 2750 | ||
2747 | m_chat->mText += " (?)"; | 2751 | m_chat.mText += " (?)"; |
2748 | 2752 | ||
2749 | add_floater_chat(*m_chat, m_history); | 2753 | add_floater_chat(m_chat, m_history); |
2750 | |||
2751 | delete m_chat; | ||
2752 | } | 2754 | } |
2753 | 2755 | ||
2754 | private: | 2756 | private: |
2755 | LLChat *m_chat; | 2757 | LLChat m_chat; |
2758 | std::string m_origMesg; | ||
2756 | const BOOL m_history; | 2759 | const BOOL m_history; |
2757 | }; | 2760 | }; |
2758 | 2761 | ||
@@ -2770,9 +2773,9 @@ void add_floater_chat(const LLChat &chat, const BOOL history) | |||
2770 | } | 2773 | } |
2771 | } | 2774 | } |
2772 | 2775 | ||
2773 | void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL history) | 2776 | void check_translate_chat(const std::string &mesg, const LLChat &chat, const BOOL history) |
2774 | { | 2777 | { |
2775 | const bool translate = LLUI::sConfigGroup->getBOOL("TranslateChat"); | 2778 | const bool translate = gSavedSettings.getBOOL("TranslateChat"); |
2776 | 2779 | ||
2777 | if (translate && chat.mSourceType != CHAT_SOURCE_SYSTEM) | 2780 | if (translate && chat.mSourceType != CHAT_SOURCE_SYSTEM) |
2778 | { | 2781 | { |
@@ -2780,9 +2783,8 @@ void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL hist | |||
2780 | // SVC-4879 | 2783 | // SVC-4879 |
2781 | const std::string &fromLang = ""; | 2784 | const std::string &fromLang = ""; |
2782 | const std::string &toLang = LLTranslate::getTranslateLanguage(); | 2785 | const std::string &toLang = LLTranslate::getTranslateLanguage(); |
2783 | LLChat *newChat = new LLChat(chat); | ||
2784 | 2786 | ||
2785 | LLHTTPClient::ResponderPtr result = ChatTranslationReceiver::build(fromLang, toLang, newChat, history); | 2787 | LLHTTPClient::ResponderPtr result = ChatTranslationReceiver::build(fromLang, toLang, chat, mesg, history); |
2786 | LLTranslate::translateMessage(result, fromLang, toLang, mesg); | 2788 | LLTranslate::translateMessage(result, fromLang, toLang, mesg); |
2787 | } | 2789 | } |
2788 | else | 2790 | else |
@@ -2961,8 +2963,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) | |||
2961 | std::string prefix = mesg.substr(0, 4); | 2963 | std::string prefix = mesg.substr(0, 4); |
2962 | if (prefix == "/me " || prefix == "/me'") | 2964 | if (prefix == "/me " || prefix == "/me'") |
2963 | { | 2965 | { |
2964 | chat.mText = from_name; | 2966 | const std::string spacer = mesg.substr(3,1); |
2965 | chat.mText += mesg.substr(3); | 2967 | mesg = mesg.substr(4); |
2968 | chat.mText = from_name + spacer + mesg; | ||
2966 | ircstyle = TRUE; | 2969 | ircstyle = TRUE; |
2967 | } | 2970 | } |
2968 | else | 2971 | else |
diff --git a/linden/indra/newview/llviewermessage.h b/linden/indra/newview/llviewermessage.h index 1a6c03b..11a3554 100644 --- a/linden/indra/newview/llviewermessage.h +++ b/linden/indra/newview/llviewermessage.h | |||
@@ -76,7 +76,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data); | |||
76 | void process_chat_from_simulator(LLMessageSystem *mesgsys, void **user_data); | 76 | void process_chat_from_simulator(LLMessageSystem *mesgsys, void **user_data); |
77 | 77 | ||
78 | void add_floater_chat(const LLChat &chat, const BOOL history); | 78 | void add_floater_chat(const LLChat &chat, const BOOL history); |
79 | void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL history); | 79 | void check_translate_chat(const std::string &mesg, const LLChat &chat, const BOOL history); |
80 | 80 | ||
81 | //void process_agent_to_new_region(LLMessageSystem *mesgsys, void **user_data); | 81 | //void process_agent_to_new_region(LLMessageSystem *mesgsys, void **user_data); |
82 | void send_agent_update(BOOL force_send, BOOL send_reliable = FALSE); | 82 | void send_agent_update(BOOL force_send, BOOL send_reliable = FALSE); |
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_login.xml b/linden/indra/newview/skins/default/xui/en-us/panel_login.xml index dda5e4d..96f3f77 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_login.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_login.xml | |||
@@ -58,7 +58,8 @@ | |||
58 | bevel_style="in" border_style="line" border_thickness="1" | 58 | bevel_style="in" border_style="line" border_thickness="1" |
59 | max_length="31" mouse_opaque="true" | 59 | max_length="31" mouse_opaque="true" |
60 | handle_edit_keys_directly="true" | 60 | handle_edit_keys_directly="true" |
61 | select_all_on_focus_received="true" /> | 61 | select_all_on_focus_received="true" |
62 | allow_translate="false" /> | ||
62 | 63 | ||
63 | 64 | ||
64 | <!-- LAST NAME --> | 65 | <!-- LAST NAME --> |
@@ -77,7 +78,8 @@ | |||
77 | bevel_style="in" border_style="line" border_thickness="1" | 78 | bevel_style="in" border_style="line" border_thickness="1" |
78 | max_length="31" mouse_opaque="true" | 79 | max_length="31" mouse_opaque="true" |
79 | handle_edit_keys_directly="true" | 80 | handle_edit_keys_directly="true" |
80 | select_all_on_focus_received="true" /> | 81 | select_all_on_focus_received="true" |
82 | allow_translate="false" /> | ||
81 | 83 | ||
82 | 84 | ||
83 | <!-- PASSWORD --> | 85 | <!-- PASSWORD --> |
@@ -96,7 +98,8 @@ | |||
96 | bevel_style="in" border_style="line" border_thickness="1" | 98 | bevel_style="in" border_style="line" border_thickness="1" |
97 | max_length="16" mouse_opaque="true" | 99 | max_length="16" mouse_opaque="true" |
98 | handle_edit_keys_directly="true" | 100 | handle_edit_keys_directly="true" |
99 | select_all_on_focus_received="true" /> | 101 | select_all_on_focus_received="true" |
102 | allow_translate="false" /> | ||
100 | <check_box name="remember_check" label="Remember password" | 103 | <check_box name="remember_check" label="Remember password" |
101 | bottom_delta="-24" left_delta="0" height="16" width="140" | 104 | bottom_delta="-24" left_delta="0" height="16" width="140" |
102 | follows="left|bottom" font="SansSerifSmall" control_name="RememberPassword" | 105 | follows="left|bottom" font="SansSerifSmall" control_name="RememberPassword" |