diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llui/lllineeditor.cpp | 295 | ||||
-rw-r--r-- | linden/indra/llui/lllineeditor.h | 24 | ||||
-rw-r--r-- | linden/indra/llui/lltexteditor.cpp | 267 | ||||
-rw-r--r-- | linden/indra/llui/lltexteditor.h | 17 | ||||
-rw-r--r-- | linden/indra/llui/lluixmltags.h | 192 |
5 files changed, 495 insertions, 300 deletions
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 66ef4c6..a3785e4 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,33 @@ 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 | translatemenu->append(new LLMenuItemCallGL("en", "English", context_translate, context_enable_translate, this)); |
236 | translatemenu->append(new LLMenuItemCallGL("English",translateText, NULL, t)); | 235 | translatemenu->append(new LLMenuItemCallGL("da", "Danish", context_translate, context_enable_translate, this)); |
237 | t=new SpellMenuBind;t->origin=this;t->word="da"; | 236 | translatemenu->append(new LLMenuItemCallGL("de", "Deutsch(German)", context_translate, context_enable_translate, this)); |
238 | translatemenu->append(new LLMenuItemCallGL("Danish",translateText, NULL, t)); | 237 | translatemenu->append(new LLMenuItemCallGL("es", "Spanish", context_translate, context_enable_translate, this)); |
239 | t=new SpellMenuBind;t->origin=this;t->word="de"; | 238 | translatemenu->append(new LLMenuItemCallGL("fr", "French", context_translate, context_enable_translate, this)); |
240 | translatemenu->append(new LLMenuItemCallGL("Deutsch(German)",translateText, NULL, t)); | 239 | translatemenu->append(new LLMenuItemCallGL("it", "Italian", context_translate, context_enable_translate, this)); |
241 | t=new SpellMenuBind;t->origin=this;t->word="es"; | 240 | translatemenu->append(new LLMenuItemCallGL("hu", "Hungarian", context_translate, context_enable_translate, this)); |
242 | translatemenu->append(new LLMenuItemCallGL("Spanish",translateText, NULL, t)); | 241 | translatemenu->append(new LLMenuItemCallGL("nl", "Dutch", context_translate, context_enable_translate, this)); |
243 | t=new SpellMenuBind;t->origin=this;t->word="fr"; | 242 | translatemenu->append(new LLMenuItemCallGL("pl", "Polish", context_translate, context_enable_translate, this)); |
244 | translatemenu->append(new LLMenuItemCallGL("French",translateText, NULL, t)); | 243 | translatemenu->append(new LLMenuItemCallGL("pt", "Portugese", context_translate, context_enable_translate, this)); |
245 | t=new SpellMenuBind;t->origin=this;t->word="it"; | 244 | translatemenu->append(new LLMenuItemCallGL("ru", "Russian", context_translate, context_enable_translate, this)); |
246 | translatemenu->append(new LLMenuItemCallGL("Italian",translateText, NULL, t)); | 245 | translatemenu->append(new LLMenuItemCallGL("tr", "Turkish", context_translate, context_enable_translate, this)); |
247 | t=new SpellMenuBind;t->origin=this;t->word="hu"; | 246 | translatemenu->append(new LLMenuItemCallGL("uk", "Ukrainian", context_translate, context_enable_translate, this)); |
248 | translatemenu->append(new LLMenuItemCallGL("Hungarian",translateText, NULL, t)); | 247 | translatemenu->append(new LLMenuItemCallGL("zh", "Chinese", context_translate, context_enable_translate, this)); |
249 | t=new SpellMenuBind;t->origin=this;t->word="nl"; | 248 | translatemenu->append(new LLMenuItemCallGL("ja", "Japanese", context_translate, context_enable_translate, this)); |
250 | translatemenu->append(new LLMenuItemCallGL("Dutch",translateText, NULL, t)); | 249 | translatemenu->append(new LLMenuItemCallGL("ko", "Korean", context_translate, context_enable_translate, this)); |
251 | t=new SpellMenuBind;t->origin=this;t->word="pl"; | 250 | |
252 | translatemenu->append(new LLMenuItemCallGL("Polish",translateText, NULL, t)); | ||
253 | t=new SpellMenuBind;t->origin=this;t->word="pt"; | ||
254 | translatemenu->append(new LLMenuItemCallGL("Portugese",translateText, NULL, t)); | ||
255 | t=new SpellMenuBind;t->origin=this;t->word="ru"; | ||
256 | translatemenu->append(new LLMenuItemCallGL("Russian",translateText, NULL, t)); | ||
257 | t=new SpellMenuBind;t->origin=this;t->word="tr"; | ||
258 | translatemenu->append(new LLMenuItemCallGL("Turkish",translateText, NULL, t)); | ||
259 | t=new SpellMenuBind;t->origin=this;t->word="uk"; | ||
260 | translatemenu->append(new LLMenuItemCallGL("Ukrainian",translateText, NULL, t)); | ||
261 | t=new SpellMenuBind;t->origin=this;t->word="zh"; | ||
262 | translatemenu->append(new LLMenuItemCallGL("Chinese",translateText, NULL, t)); | ||
263 | t=new SpellMenuBind;t->origin=this;t->word="ja"; | ||
264 | translatemenu->append(new LLMenuItemCallGL("Japanese",translateText, NULL, t)); | ||
265 | t=new SpellMenuBind;t->origin=this;t->word="ko"; | ||
266 | translatemenu->append(new LLMenuItemCallGL("Korean",translateText, NULL, t)); | ||
267 | menu->appendMenu(translatemenu); | 251 | menu->appendMenu(translatemenu); |
268 | menu->appendSeparator("Spelsep"); | 252 | menu->appendSeparator("Spelsep"); |
269 | //menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); | 253 | //menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); |
@@ -432,14 +416,23 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) | |||
432 | setCursor(llmin((S32)mText.length(), getCursor())); | 416 | setCursor(llmin((S32)mText.length(), getCursor())); |
433 | 417 | ||
434 | // Set current history line to end of history. | 418 | // Set current history line to end of history. |
435 | mCurrentHistoryLine = mLineHistory.end() - 1; | 419 | // RC Fix, its really not safe to just take 1 of the end itterator, if end==begin |
420 | // that leaves an invalid state upseting the secure STL checks | ||
421 | if(mLineHistory.empty()) | ||
422 | { | ||
423 | mCurrentHistoryLine = mLineHistory.begin(); | ||
424 | } | ||
425 | else | ||
426 | { | ||
427 | mCurrentHistoryLine = mLineHistory.end() - 1; | ||
428 | } | ||
436 | 429 | ||
437 | mPrevText = mText; | 430 | mPrevText = mText; |
438 | } | 431 | } |
439 | 432 | ||
440 | 433 | ||
441 | // Picks a new cursor position based on the actual screen size of text being drawn. | 434 | // Picks a new cursor position based on the actual screen size of text being drawn. |
442 | S32 LLLineEditor::calculateCursorFromMouse( S32 local_mouse_x ) | 435 | S32 LLLineEditor::calculateCursorFromMouse( S32 local_mouse_x ) const |
443 | { | 436 | { |
444 | const llwchar* wtext = mText.getWString().c_str(); | 437 | const llwchar* wtext = mText.getWString().c_str(); |
445 | LLWString asterix_text; | 438 | LLWString asterix_text; |
@@ -517,17 +510,30 @@ void LLLineEditor::deselect() | |||
517 | mIsSelecting = FALSE; | 510 | mIsSelecting = FALSE; |
518 | } | 511 | } |
519 | 512 | ||
513 | BOOL LLLineEditor::context_enable_cut(void* data) | ||
514 | { | ||
515 | LLLineEditor* line = (LLLineEditor*)data; | ||
516 | return (line && line->canCut()); | ||
517 | } | ||
520 | 518 | ||
521 | void LLLineEditor::context_cut(void* data) | 519 | void LLLineEditor::context_cut(void* data) |
522 | { | 520 | { |
523 | LLLineEditor* line = (LLLineEditor*)data; | 521 | LLLineEditor* line = (LLLineEditor*)data; |
524 | if(line)line->cut(); | 522 | if(line)line->cut(); |
525 | } | 523 | } |
524 | |||
525 | BOOL LLLineEditor::context_enable_copy(void* data) | ||
526 | { | ||
527 | LLLineEditor* line = (LLLineEditor*)data; | ||
528 | return (line &&line->canCopy()); | ||
529 | } | ||
530 | |||
526 | void LLLineEditor::context_copy(void* data) | 531 | void LLLineEditor::context_copy(void* data) |
527 | { | 532 | { |
528 | LLLineEditor* line = (LLLineEditor*)data; | 533 | LLLineEditor* line = (LLLineEditor*)data; |
529 | if(line)line->copy(); | 534 | if(line)line->copy(); |
530 | } | 535 | } |
536 | |||
531 | void LLLineEditor::spell_correct(void* data) | 537 | void LLLineEditor::spell_correct(void* data) |
532 | { | 538 | { |
533 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | 539 | SpellMenuBind* tempBind = (SpellMenuBind*)data; |
@@ -539,31 +545,57 @@ void LLLineEditor::spell_correct(void* data) | |||
539 | 545 | ||
540 | } | 546 | } |
541 | } | 547 | } |
542 | void LLLineEditor::translateText(void * data) | 548 | |
549 | BOOL LLLineEditor::context_enable_translate(void* data) | ||
543 | { | 550 | { |
544 | SpellMenuBind* t = (SpellMenuBind*)data; | 551 | LLLineEditor* line = (LLLineEditor*)data; |
545 | LLLineEditor* line = t->origin; | 552 | return line && line->canTranslate(); |
546 | const std::string &toLang = t->word;//LLTranslate::getTranslateLanguage(); | ||
547 | LLHTTPClient::ResponderPtr result = LineChatTranslationReceiver::build(toLang,line); | ||
548 | S32 left_pos = llmin( line->mSelectionStart, line->mSelectionEnd ); | ||
549 | S32 length = abs( line->mSelectionStart - line->mSelectionEnd ); | ||
550 | LLTranslate::translateMessage(result,"", toLang, line->mText.getString().substr(left_pos, length)); | ||
551 | } | 553 | } |
554 | |||
555 | void LLLineEditor::context_translate(void * data) | ||
556 | { | ||
557 | LLLineEditor* line = (LLLineEditor*)data; | ||
558 | LLMenuGL* menu = line ? (LLMenuGL*)(line->mPopupMenuHandle.get()) : NULL; | ||
559 | LLMenuGL* translate_menu = menu ? menu->getChildMenuByName("Translate To", TRUE) : NULL; | ||
560 | if (!translate_menu) | ||
561 | { | ||
562 | return; | ||
563 | } | ||
564 | const std::string to_lang = translate_menu->getHighlightedItem()->getName(); | ||
565 | |||
566 | bool has_text = false; | ||
567 | S32 start, length; | ||
568 | if (line->hasSelection()) | ||
569 | { | ||
570 | // translate selection | ||
571 | start = llmin(line->mSelectionStart, line->mSelectionEnd); | ||
572 | length = abs(line->mSelectionEnd - line->mSelectionStart); | ||
573 | has_text = length > 0; | ||
574 | } | ||
575 | else | ||
576 | { | ||
577 | // translate one word at click position | ||
578 | S32 at = line->calculateCursorFromMouse(line->mLastContextMenuX); | ||
579 | has_text = line->getWordBoundriesAt(at, &start, &length); | ||
580 | } | ||
581 | |||
582 | if (has_text) | ||
583 | { | ||
584 | std::string to_translate = wstring_to_utf8str(line->getWText().substr(start, length)); | ||
585 | LLHTTPClient::ResponderPtr result = LineChatTranslationReceiver::build(to_lang, line, start, length); | ||
586 | LLTranslate::translateMessage(result,"", to_lang, to_translate); | ||
587 | } | ||
588 | } | ||
589 | |||
552 | void LLLineEditor::spell_show(void * data) | 590 | void LLLineEditor::spell_show(void * data) |
553 | { | 591 | { |
554 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | 592 | SpellMenuBind* tempBind = (SpellMenuBind*)data; |
555 | LLLineEditor* line = tempBind->origin; | 593 | LLLineEditor* line = tempBind->origin; |
556 | 594 | ||
557 | if( tempBind && line) | 595 | if (tempBind && line) |
558 | { | 596 | { |
559 | if (tempBind->word == "Show Misspellings") | 597 | BOOL show = (tempBind->word == "Show Misspellings"); |
560 | { | 598 | glggHunSpell->setSpellCheckHighlight(show); |
561 | line->mShowMisspellings = TRUE; | ||
562 | } | ||
563 | else | ||
564 | { | ||
565 | line->mShowMisspellings = FALSE; | ||
566 | } | ||
567 | } | 599 | } |
568 | } | 600 | } |
569 | 601 | ||
@@ -623,18 +655,36 @@ void LLLineEditor::spell_add(void* data) | |||
623 | } | 655 | } |
624 | } | 656 | } |
625 | 657 | ||
658 | BOOL LLLineEditor::context_enable_paste(void* data) | ||
659 | { | ||
660 | LLLineEditor* line = (LLLineEditor*)data; | ||
661 | return (line && line->canPaste()); | ||
662 | } | ||
663 | |||
626 | void LLLineEditor::context_paste(void* data) | 664 | void LLLineEditor::context_paste(void* data) |
627 | { | 665 | { |
628 | LLLineEditor* line = (LLLineEditor*)data; | 666 | LLLineEditor* line = (LLLineEditor*)data; |
629 | if(line)line->paste(); | 667 | if(line)line->paste(); |
630 | } | 668 | } |
631 | 669 | ||
670 | BOOL LLLineEditor::context_enable_delete(void* data) | ||
671 | { | ||
672 | LLLineEditor* line = (LLLineEditor*)data; | ||
673 | return (line && line->canDoDelete()); | ||
674 | } | ||
675 | |||
632 | void LLLineEditor::context_delete(void* data) | 676 | void LLLineEditor::context_delete(void* data) |
633 | { | 677 | { |
634 | LLLineEditor* line = (LLLineEditor*)data; | 678 | LLLineEditor* line = (LLLineEditor*)data; |
635 | if(line)line->doDelete(); | 679 | if(line)line->doDelete(); |
636 | } | 680 | } |
637 | 681 | ||
682 | BOOL LLLineEditor::context_enable_selectall(void* data) | ||
683 | { | ||
684 | LLLineEditor* line = (LLLineEditor*)data; | ||
685 | return (line && line->canSelectAll()); | ||
686 | } | ||
687 | |||
638 | void LLLineEditor::context_selectall(void* data) | 688 | void LLLineEditor::context_selectall(void* data) |
639 | { | 689 | { |
640 | LLLineEditor* line = (LLLineEditor*)data; | 690 | LLLineEditor* line = (LLLineEditor*)data; |
@@ -738,7 +788,8 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
738 | 788 | ||
739 | //setCursorAtLocalPos( x); | 789 | //setCursorAtLocalPos( x); |
740 | S32 wordStart = 0; | 790 | S32 wordStart = 0; |
741 | S32 wordEnd = calculateCursorFromMouse(x); | 791 | S32 wordLen = 0; |
792 | S32 pos = calculateCursorFromMouse(x); | ||
742 | 793 | ||
743 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | 794 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); |
744 | if (menu) | 795 | if (menu) |
@@ -761,43 +812,28 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
761 | } | 812 | } |
762 | suggestionMenuItems.clear(); | 813 | suggestionMenuItems.clear(); |
763 | 814 | ||
764 | menu->setItemVisible("Translate To", !mReadOnly); | ||
765 | menu->setItemVisible("Transep", !mReadOnly); | ||
766 | |||
767 | // spell_check="true" in xui | 815 | // spell_check="true" in xui |
816 | menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable); | ||
768 | if (!mReadOnly && mSpellCheckable) | 817 | if (!mReadOnly && mSpellCheckable) |
769 | { | 818 | { |
770 | const LLWString& text = mText.getWString(); | ||
771 | |||
772 | // search for word matches | 819 | // search for word matches |
773 | if (LLTextEditor::isPartOfWord(text[wordEnd])) | 820 | bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen); |
821 | if (is_word_part) | ||
774 | { | 822 | { |
775 | // Select word the cursor is over | 823 | const LLWString& text = mText.getWString(); |
776 | while ((wordEnd > 0) && LLTextEditor::isPartOfWord(text[wordEnd-1])) | 824 | std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen)); |
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)); | ||
788 | 825 | ||
789 | if (!glggHunSpell->isSpelledRight(selectedWord)) | 826 | if (!glggHunSpell->isSpelledRight(selectedWord)) |
790 | { | 827 | { |
791 | //misspelled word here, and you have just right clicked on it! | 828 | //misspelled word here, and you have just right clicked on it! |
792 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); | 829 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); |
793 | //menu->setItemVisible("Transep",(suggs.size()>0)); | ||
794 | 830 | ||
795 | for (int i = 0; i<(int)suggs.size() ;i++) | 831 | for (int i = 0; i<(int)suggs.size() ;i++) |
796 | { | 832 | { |
797 | SpellMenuBind * tempStruct = new SpellMenuBind; | 833 | SpellMenuBind * tempStruct = new SpellMenuBind; |
798 | tempStruct->origin = this; | 834 | tempStruct->origin = this; |
799 | tempStruct->word = suggs[i]; | 835 | tempStruct->word = suggs[i]; |
800 | tempStruct->wordPositionEnd = wordEnd; | 836 | tempStruct->wordPositionEnd = wordStart + wordLen; |
801 | tempStruct->wordPositionStart=wordStart; | 837 | tempStruct->wordPositionStart=wordStart; |
802 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | 838 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( |
803 | tempStruct->word, spell_correct, NULL, tempStruct); | 839 | tempStruct->word, spell_correct, NULL, tempStruct); |
@@ -809,7 +845,7 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
809 | SpellMenuBind * tempStruct = new SpellMenuBind; | 845 | SpellMenuBind * tempStruct = new SpellMenuBind; |
810 | tempStruct->origin = this; | 846 | tempStruct->origin = this; |
811 | tempStruct->word = selectedWord; | 847 | tempStruct->word = selectedWord; |
812 | tempStruct->wordPositionEnd = wordEnd; | 848 | tempStruct->wordPositionEnd = wordStart + wordLen; |
813 | tempStruct->wordPositionStart=wordStart; | 849 | tempStruct->wordPositionStart=wordStart; |
814 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | 850 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( |
815 | "Add Word", spell_add, NULL, tempStruct); | 851 | "Add Word", spell_add, NULL, tempStruct); |
@@ -821,7 +857,7 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
821 | 857 | ||
822 | SpellMenuBind * tempStruct = new SpellMenuBind; | 858 | SpellMenuBind * tempStruct = new SpellMenuBind; |
823 | tempStruct->origin = this; | 859 | tempStruct->origin = this; |
824 | if (mShowMisspellings) | 860 | if (glggHunSpell->getSpellCheckHighlight()) |
825 | { | 861 | { |
826 | tempStruct->word = "Hide Misspellings"; | 862 | tempStruct->word = "Hide Misspellings"; |
827 | } | 863 | } |
@@ -836,6 +872,7 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
836 | menu->append(suggMenuItem); | 872 | menu->append(suggMenuItem); |
837 | } | 873 | } |
838 | 874 | ||
875 | mLastContextMenuX = x; | ||
839 | menu->buildDrawLabels(); | 876 | menu->buildDrawLabels(); |
840 | menu->updateParent(LLMenuGL::sMenuContainer); | 877 | menu->updateParent(LLMenuGL::sMenuContainer); |
841 | LLMenuGL::showPopup(this, menu, x, y); | 878 | LLMenuGL::showPopup(this, menu, x, y); |
@@ -1109,13 +1146,9 @@ void LLLineEditor::setSelection(S32 start, S32 end) | |||
1109 | { | 1146 | { |
1110 | S32 len = mText.length(); | 1147 | S32 len = mText.length(); |
1111 | 1148 | ||
1112 | mIsSelecting = TRUE; | 1149 | mSelectionStart = llclamp(start, 0, len); |
1113 | 1150 | mSelectionEnd = llclamp(end, 0, len); | |
1114 | // JC, yes, this seems odd, but I think you have to presume a | 1151 | 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 | } | 1152 | } |
1120 | 1153 | ||
1121 | void LLLineEditor::setDrawAsterixes(BOOL b) | 1154 | void LLLineEditor::setDrawAsterixes(BOOL b) |
@@ -1152,6 +1185,26 @@ S32 LLLineEditor::nextWordPos(S32 cursorPos) const | |||
1152 | return cursorPos; | 1185 | return cursorPos; |
1153 | } | 1186 | } |
1154 | 1187 | ||
1188 | BOOL LLLineEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const | ||
1189 | { | ||
1190 | const LLWString& wtext = mText.getWString(); | ||
1191 | S32 pos = at; | ||
1192 | if (LLTextEditor::isPartOfWord(wtext[pos])) | ||
1193 | { | ||
1194 | while ( (pos > 0) && LLTextEditor::isPartOfWord(wtext[pos - 1]) ) | ||
1195 | { | ||
1196 | pos--; | ||
1197 | } | ||
1198 | *word_begin = pos; | ||
1199 | while ( (pos < (S32)wtext.length()) && LLTextEditor::isPartOfWord(wtext[pos]) ) | ||
1200 | { | ||
1201 | pos++; | ||
1202 | } | ||
1203 | *word_length = pos - *word_begin; | ||
1204 | return TRUE; | ||
1205 | } | ||
1206 | return FALSE; | ||
1207 | } | ||
1155 | 1208 | ||
1156 | BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) | 1209 | BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) |
1157 | { | 1210 | { |
@@ -1315,6 +1368,37 @@ void LLLineEditor::spellReplace(SpellMenuBind* spellData) | |||
1315 | 1368 | ||
1316 | 1369 | ||
1317 | } | 1370 | } |
1371 | |||
1372 | void LLLineEditor::translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length) | ||
1373 | { | ||
1374 | //*TODO: should probably check if the content was modified since the http query | ||
1375 | // was made, so we don't insert text in the wrong place. | ||
1376 | BOOL replace = gSavedSettings.getBOOL("EmeraldTranslateReplace"); | ||
1377 | std::string text = replace ? translation : " (" + translation + ")"; | ||
1378 | S32 pos = replace ? orig_start : orig_start + orig_length; | ||
1379 | if (replace) | ||
1380 | { | ||
1381 | mText.erase(orig_start, orig_length); | ||
1382 | } | ||
1383 | insert(text, pos); | ||
1384 | |||
1385 | S32 text_wlen = utf8str_to_wstring(text).length(); | ||
1386 | if (hasSelection()) | ||
1387 | { | ||
1388 | setSelection(pos, pos + text_wlen); | ||
1389 | } | ||
1390 | setCursor(pos + text_wlen); | ||
1391 | } | ||
1392 | |||
1393 | BOOL LLLineEditor::canTranslate() const | ||
1394 | { | ||
1395 | // if allow_translate="true" in xui, and if other factors permit, we allow it | ||
1396 | S32 pos = calculateCursorFromMouse(mLastContextMenuX); | ||
1397 | const LLWString& wtext = getWText(); | ||
1398 | bool is_word_part = (pos > -1) && LLTextEditor::isPartOfWord(wtext[pos]); | ||
1399 | return (mAllowTranslate && !mReadOnly && (is_word_part || hasSelection())); | ||
1400 | } | ||
1401 | |||
1318 | void LLLineEditor::insert(std::string what, S32 wher) | 1402 | void LLLineEditor::insert(std::string what, S32 wher) |
1319 | { | 1403 | { |
1320 | LLLineEditorRollback rollback(this); | 1404 | LLLineEditorRollback rollback(this); |
@@ -1925,7 +2009,7 @@ void LLLineEditor::drawMisspelled(LLRect background) | |||
1925 | } | 2009 | } |
1926 | } | 2010 | } |
1927 | 2011 | ||
1928 | if (mShowMisspellings) | 2012 | if (glggHunSpell->getSpellCheckHighlight()) |
1929 | { | 2013 | { |
1930 | for (int i =0; i<(int)misspellLocations.size(); i++) | 2014 | for (int i =0; i<(int)misspellLocations.size(); i++) |
1931 | { | 2015 | { |
@@ -2830,6 +2914,11 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory | |||
2830 | { | 2914 | { |
2831 | line_editor->setSpellCheckable(spell_checking); | 2915 | line_editor->setSpellCheckable(spell_checking); |
2832 | } | 2916 | } |
2917 | BOOL allow_translate = TRUE; | ||
2918 | if (node->getAttributeBOOL("allow_translate", allow_translate)) | ||
2919 | { | ||
2920 | line_editor->setAllowTranslate(allow_translate); | ||
2921 | } | ||
2833 | 2922 | ||
2834 | line_editor->setColorParameters(node); | 2923 | line_editor->setColorParameters(node); |
2835 | 2924 | ||
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..fdf8bcf 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,30 @@ 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 | translatemenu->append(new LLMenuItemCallGL("en", "English", context_translate, context_enable_translate, this)); |
402 | translatemenu->append(new LLMenuItemCallGL("English",translateText, NULL, t)); | 402 | translatemenu->append(new LLMenuItemCallGL("da", "Danish", context_translate, context_enable_translate, this)); |
403 | t=new SpellMenuBind;t->origin=this;t->word="da"; | 403 | translatemenu->append(new LLMenuItemCallGL("de", "Deutsch(German)", context_translate, context_enable_translate, this)); |
404 | translatemenu->append(new LLMenuItemCallGL("Danish",translateText, NULL, t)); | 404 | translatemenu->append(new LLMenuItemCallGL("es", "Spanish", context_translate, context_enable_translate, this)); |
405 | t=new SpellMenuBind;t->origin=this;t->word="de"; | 405 | translatemenu->append(new LLMenuItemCallGL("fr", "French", context_translate, context_enable_translate, this)); |
406 | translatemenu->append(new LLMenuItemCallGL("Deutsch(German)",translateText, NULL, t)); | 406 | translatemenu->append(new LLMenuItemCallGL("it", "Italian", context_translate, context_enable_translate, this)); |
407 | t=new SpellMenuBind;t->origin=this;t->word="es"; | 407 | translatemenu->append(new LLMenuItemCallGL("hu", "Hungarian", context_translate, context_enable_translate, this)); |
408 | translatemenu->append(new LLMenuItemCallGL("Spanish",translateText, NULL, t)); | 408 | translatemenu->append(new LLMenuItemCallGL("nl", "Dutch", context_translate, context_enable_translate, this)); |
409 | t=new SpellMenuBind;t->origin=this;t->word="fr"; | 409 | translatemenu->append(new LLMenuItemCallGL("pl", "Polish", context_translate, context_enable_translate, this)); |
410 | translatemenu->append(new LLMenuItemCallGL("French",translateText, NULL, t)); | 410 | translatemenu->append(new LLMenuItemCallGL("pt", "Portugese", context_translate, context_enable_translate, this)); |
411 | t=new SpellMenuBind;t->origin=this;t->word="it"; | 411 | translatemenu->append(new LLMenuItemCallGL("ru", "Russian", context_translate, context_enable_translate, this)); |
412 | translatemenu->append(new LLMenuItemCallGL("Italian",translateText, NULL, t)); | 412 | translatemenu->append(new LLMenuItemCallGL("tr", "Turkish", context_translate, context_enable_translate, this)); |
413 | t=new SpellMenuBind;t->origin=this;t->word="hu"; | 413 | translatemenu->append(new LLMenuItemCallGL("uk", "Ukrainian", context_translate, context_enable_translate, this)); |
414 | translatemenu->append(new LLMenuItemCallGL("Hungarian",translateText, NULL, t)); | 414 | translatemenu->append(new LLMenuItemCallGL("zh", "Chinese", context_translate, context_enable_translate, this)); |
415 | t=new SpellMenuBind;t->origin=this;t->word="nl"; | 415 | translatemenu->append(new LLMenuItemCallGL("ja", "Japanese", context_translate, context_enable_translate, this)); |
416 | translatemenu->append(new LLMenuItemCallGL("Dutch",translateText, NULL, t)); | 416 | translatemenu->append(new LLMenuItemCallGL("ko", "Korean", context_translate, context_enable_translate, this)); |
417 | t=new SpellMenuBind;t->origin=this;t->word="pl"; | ||
418 | translatemenu->append(new LLMenuItemCallGL("Polish",translateText, NULL, t)); | ||
419 | t=new SpellMenuBind;t->origin=this;t->word="pt"; | ||
420 | translatemenu->append(new LLMenuItemCallGL("Portugese",translateText, NULL, t)); | ||
421 | t=new SpellMenuBind;t->origin=this;t->word="ru"; | ||
422 | translatemenu->append(new LLMenuItemCallGL("Russian",translateText, NULL, t)); | ||
423 | t=new SpellMenuBind;t->origin=this;t->word="tr"; | ||
424 | translatemenu->append(new LLMenuItemCallGL("Turkish",translateText, NULL, t)); | ||
425 | t=new SpellMenuBind;t->origin=this;t->word="uk"; | ||
426 | translatemenu->append(new LLMenuItemCallGL("Ukrainian",translateText, NULL, t)); | ||
427 | t=new SpellMenuBind;t->origin=this;t->word="zh"; | ||
428 | translatemenu->append(new LLMenuItemCallGL("Chinese",translateText, NULL, t)); | ||
429 | t=new SpellMenuBind;t->origin=this;t->word="ja"; | ||
430 | translatemenu->append(new LLMenuItemCallGL("Japanese",translateText, NULL, t)); | ||
431 | t=new SpellMenuBind;t->origin=this;t->word="ko"; | ||
432 | translatemenu->append(new LLMenuItemCallGL("Korean",translateText, NULL, t)); | ||
433 | 417 | ||
434 | menu->appendMenu(translatemenu); | 418 | menu->appendMenu(translatemenu); |
435 | menu->appendSeparator("Spelsep"); | 419 | menu->appendSeparator("Spelsep"); |
@@ -439,7 +423,6 @@ LLTextEditor::LLTextEditor( | |||
439 | mPopupMenuHandle = menu->getHandle(); | 423 | mPopupMenuHandle = menu->getHandle(); |
440 | } | 424 | } |
441 | 425 | ||
442 | |||
443 | LLTextEditor::~LLTextEditor() | 426 | LLTextEditor::~LLTextEditor() |
444 | { | 427 | { |
445 | gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() | 428 | gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() |
@@ -457,27 +440,72 @@ LLTextEditor::~LLTextEditor() | |||
457 | std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); | 440 | std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); |
458 | LLView::deleteViewByHandle(mPopupMenuHandle); | 441 | LLView::deleteViewByHandle(mPopupMenuHandle); |
459 | } | 442 | } |
443 | |||
444 | BOOL LLTextEditor::context_enable_cut(void* data) | ||
445 | { | ||
446 | LLTextEditor* line = (LLTextEditor*)data; | ||
447 | return (line && line->canCut()); | ||
448 | } | ||
449 | |||
460 | void LLTextEditor::context_cut(void* data) | 450 | void LLTextEditor::context_cut(void* data) |
461 | { | 451 | { |
462 | LLTextEditor* line = (LLTextEditor*)data; | 452 | LLTextEditor* line = (LLTextEditor*)data; |
463 | if(line)line->cut(); | 453 | if(line)line->cut(); |
464 | } | 454 | } |
455 | |||
456 | BOOL LLTextEditor::context_enable_copy(void* data) | ||
457 | { | ||
458 | LLTextEditor* line = (LLTextEditor*)data; | ||
459 | return (line && line->canCopy()); | ||
460 | } | ||
461 | |||
465 | void LLTextEditor::context_copy(void* data) | 462 | void LLTextEditor::context_copy(void* data) |
466 | { | 463 | { |
467 | LLTextEditor* line = (LLTextEditor*)data; | 464 | LLTextEditor* line = (LLTextEditor*)data; |
468 | if(line)line->copy(); | 465 | if(line)line->copy(); |
469 | } | 466 | } |
470 | void LLTextEditor::translateText(void * data) | 467 | |
468 | BOOL LLTextEditor::context_enable_translate(void * data) | ||
471 | { | 469 | { |
472 | SpellMenuBind* t = (SpellMenuBind*)data; | 470 | LLTextEditor* editor = (LLTextEditor*)data; |
473 | LLTextEditor* line = t->origin; | 471 | return editor && editor->canTranslate(); |
474 | const std::string &toLang = t->word;//LLTranslate::getTranslateLanguage(); | 472 | } |
475 | LLHTTPClient::ResponderPtr result = TextChatTranslationReceiver::build(toLang,line); | ||
476 | 473 | ||
477 | S32 left_pos = llmin( line->mSelectionStart, line->mSelectionEnd ); | 474 | void LLTextEditor::context_translate(void * data) |
478 | S32 length = abs( line->mSelectionStart - line->mSelectionEnd ); | 475 | { |
479 | LLTranslate::translateMessage(result,"", toLang, line->getText().substr(left_pos, length)); | 476 | LLTextEditor* line = (LLTextEditor*)data; |
477 | LLMenuGL* menu = line ? (LLMenuGL*)(line->mPopupMenuHandle.get()) : NULL; | ||
478 | LLMenuGL* translate_menu = menu ? menu->getChildMenuByName("Translate To", TRUE) : NULL; | ||
479 | if (!translate_menu) | ||
480 | { | ||
481 | return; | ||
482 | } | ||
483 | const std::string to_lang = translate_menu->getHighlightedItem()->getName(); | ||
484 | |||
485 | bool has_text = false; | ||
486 | S32 start, length; | ||
487 | if (line->hasSelection()) | ||
488 | { | ||
489 | // translate selection | ||
490 | start = llmin(line->mSelectionStart, line->mSelectionEnd); | ||
491 | length = abs(line->mSelectionEnd - line->mSelectionStart); | ||
492 | has_text = length > 0; | ||
493 | } | ||
494 | else | ||
495 | { | ||
496 | // translate one word as click position | ||
497 | S32 at = line->getCursorPosFromLocalCoord(line->mLastContextMenuX, line->mLastContextMenuY, TRUE); | ||
498 | has_text = line->getWordBoundriesAt(at, &start, &length); | ||
499 | } | ||
500 | |||
501 | if (has_text) | ||
502 | { | ||
503 | const std::string to_translate = wstring_to_utf8str(line->getWText().substr(start, length)); | ||
504 | LLHTTPClient::ResponderPtr result = TextChatTranslationReceiver::build(to_lang, line, start, length); | ||
505 | LLTranslate::translateMessage(result,"", to_lang, to_translate); | ||
506 | } | ||
480 | } | 507 | } |
508 | |||
481 | void LLTextEditor::spell_correct(void* data) | 509 | void LLTextEditor::spell_correct(void* data) |
482 | { | 510 | { |
483 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | 511 | SpellMenuBind* tempBind = (SpellMenuBind*)data; |
@@ -496,14 +524,8 @@ void LLTextEditor::spell_show(void * data) | |||
496 | 524 | ||
497 | if (tempBind && line) | 525 | if (tempBind && line) |
498 | { | 526 | { |
499 | if (tempBind->word == "Show Misspellings") | 527 | BOOL show = (tempBind->word == "Show Misspellings"); |
500 | { | 528 | glggHunSpell->setSpellCheckHighlight(show); |
501 | glggHunSpell->setSpellCheckHighlight(TRUE); | ||
502 | } | ||
503 | else | ||
504 | { | ||
505 | glggHunSpell->setSpellCheckHighlight(FALSE); | ||
506 | } | ||
507 | } | 529 | } |
508 | } | 530 | } |
509 | 531 | ||
@@ -555,16 +577,37 @@ void LLTextEditor::spell_add(void* data) | |||
555 | tempBind->origin->mPrevSpelledText.erase();//make it update | 577 | tempBind->origin->mPrevSpelledText.erase();//make it update |
556 | } | 578 | } |
557 | } | 579 | } |
580 | |||
581 | BOOL LLTextEditor::context_enable_paste(void* data) | ||
582 | { | ||
583 | LLTextEditor* line = (LLTextEditor*)data; | ||
584 | return(line && line->canPaste()); | ||
585 | } | ||
586 | |||
558 | void LLTextEditor::context_paste(void* data) | 587 | void LLTextEditor::context_paste(void* data) |
559 | { | 588 | { |
560 | LLTextEditor* line = (LLTextEditor*)data; | 589 | LLTextEditor* line = (LLTextEditor*)data; |
561 | if(line)line->paste(); | 590 | if(line)line->paste(); |
562 | } | 591 | } |
592 | |||
593 | BOOL LLTextEditor::context_enable_delete(void* data) | ||
594 | { | ||
595 | LLTextEditor* line = (LLTextEditor*)data; | ||
596 | return (line && line->canDoDelete()); | ||
597 | } | ||
598 | |||
563 | void LLTextEditor::context_delete(void* data) | 599 | void LLTextEditor::context_delete(void* data) |
564 | { | 600 | { |
565 | LLTextEditor* line = (LLTextEditor*)data; | 601 | LLTextEditor* line = (LLTextEditor*)data; |
566 | if(line)line->doDelete(); | 602 | if(line)line->doDelete(); |
567 | } | 603 | } |
604 | |||
605 | BOOL LLTextEditor::context_enable_selectall(void* data) | ||
606 | { | ||
607 | LLTextEditor* line = (LLTextEditor*)data; | ||
608 | return (line && line->canSelectAll()); | ||
609 | } | ||
610 | |||
568 | void LLTextEditor::context_selectall(void* data) | 611 | void LLTextEditor::context_selectall(void* data) |
569 | { | 612 | { |
570 | LLTextEditor* line = (LLTextEditor*)data; | 613 | LLTextEditor* line = (LLTextEditor*)data; |
@@ -947,6 +990,26 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const | |||
947 | return cursorPos; | 990 | return cursorPos; |
948 | } | 991 | } |
949 | 992 | ||
993 | BOOL LLTextEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const | ||
994 | { | ||
995 | S32 pos = at; | ||
996 | if (isPartOfWord(mWText[pos])) | ||
997 | { | ||
998 | while ( (pos > 0) && isPartOfWord(mWText[pos - 1]) ) | ||
999 | { | ||
1000 | pos--; | ||
1001 | } | ||
1002 | *word_begin = pos; | ||
1003 | while ( (pos < getLength()) && isPartOfWord(mWText[pos]) ) | ||
1004 | { | ||
1005 | pos++; | ||
1006 | } | ||
1007 | *word_length = pos - *word_begin; | ||
1008 | return TRUE; | ||
1009 | } | ||
1010 | return FALSE; | ||
1011 | } | ||
1012 | |||
950 | S32 LLTextEditor::getLineStart( S32 line ) const | 1013 | S32 LLTextEditor::getLineStart( S32 line ) const |
951 | { | 1014 | { |
952 | S32 num_lines = getLineCount(); | 1015 | S32 num_lines = getLineCount(); |
@@ -1439,7 +1502,8 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1439 | 1502 | ||
1440 | //setCursorAtLocalPos( x, y, TRUE ); | 1503 | //setCursorAtLocalPos( x, y, TRUE ); |
1441 | S32 wordStart = 0; | 1504 | S32 wordStart = 0; |
1442 | S32 wordEnd = getCursorPosFromLocalCoord(x,y,TRUE); | 1505 | S32 wordLen = 0; |
1506 | S32 pos = getCursorPosFromLocalCoord(x,y,TRUE); | ||
1443 | 1507 | ||
1444 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | 1508 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); |
1445 | if (menu) | 1509 | if (menu) |
@@ -1458,41 +1522,27 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1458 | } | 1522 | } |
1459 | suggestionMenuItems.clear(); | 1523 | suggestionMenuItems.clear(); |
1460 | 1524 | ||
1461 | menu->setItemVisible("Translate To", !mReadOnly); | ||
1462 | menu->setItemVisible("Transep", !mReadOnly); | ||
1463 | |||
1464 | // spell_check="true" in xui | 1525 | // spell_check="true" in xui |
1526 | menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable); | ||
1465 | if (!mReadOnly && mSpellCheckable) | 1527 | if (!mReadOnly && mSpellCheckable) |
1466 | { | 1528 | { |
1467 | const LLWString &text = mWText; | 1529 | bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen); |
1468 | 1530 | if (is_word_part) | |
1469 | if (isPartOfWord(text[wordEnd]) && !mReadOnly) | ||
1470 | { | 1531 | { |
1471 | // Select word the cursor is over | 1532 | const LLWString &text = mWText; |
1472 | while ((wordEnd > 0) && isPartOfWord(text[wordEnd-1])) | 1533 | std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen)); |
1473 | { | ||
1474 | wordEnd--; | ||
1475 | } | ||
1476 | wordStart = wordEnd; | ||
1477 | //startSelection(); | ||
1478 | 1534 | ||
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)); | ||
1484 | if (!glggHunSpell->isSpelledRight(selectedWord)) | 1535 | if (!glggHunSpell->isSpelledRight(selectedWord)) |
1485 | { | 1536 | { |
1486 | //misspelled word here, and you have just right clicked on it! | 1537 | //misspelled word here, and you have just right clicked on it! |
1487 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); | 1538 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); |
1488 | 1539 | ||
1489 | //menu->setItemVisible("Transep",(suggs.size()>0)); | ||
1490 | for (int i = 0; i<(int)suggs.size(); i++) | 1540 | for (int i = 0; i<(int)suggs.size(); i++) |
1491 | { | 1541 | { |
1492 | SpellMenuBind * tempStruct = new SpellMenuBind; | 1542 | SpellMenuBind * tempStruct = new SpellMenuBind; |
1493 | tempStruct->origin = this; | 1543 | tempStruct->origin = this; |
1494 | tempStruct->word = suggs[i]; | 1544 | tempStruct->word = suggs[i]; |
1495 | tempStruct->wordPositionEnd = wordEnd; | 1545 | tempStruct->wordPositionEnd = wordStart + wordLen; |
1496 | tempStruct->wordPositionStart=wordStart; | 1546 | tempStruct->wordPositionStart=wordStart; |
1497 | tempStruct->wordY=y; | 1547 | tempStruct->wordY=y; |
1498 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | 1548 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( |
@@ -1504,7 +1554,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1504 | SpellMenuBind * tempStruct = new SpellMenuBind; | 1554 | SpellMenuBind * tempStruct = new SpellMenuBind; |
1505 | tempStruct->origin = this; | 1555 | tempStruct->origin = this; |
1506 | tempStruct->word = selectedWord; | 1556 | tempStruct->word = selectedWord; |
1507 | tempStruct->wordPositionEnd = wordEnd; | 1557 | tempStruct->wordPositionEnd = wordStart + wordLen; |
1508 | tempStruct->wordPositionStart=wordStart; | 1558 | tempStruct->wordPositionStart=wordStart; |
1509 | tempStruct->wordY=y; | 1559 | tempStruct->wordY=y; |
1510 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | 1560 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( |
@@ -1517,7 +1567,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1517 | 1567 | ||
1518 | SpellMenuBind * tempStruct = new SpellMenuBind; | 1568 | SpellMenuBind * tempStruct = new SpellMenuBind; |
1519 | tempStruct->origin = this; | 1569 | tempStruct->origin = this; |
1520 | if (mShowMisspellings) | 1570 | if (glggHunSpell->getSpellCheckHighlight()) |
1521 | { | 1571 | { |
1522 | tempStruct->word = "Hide Misspellings"; | 1572 | tempStruct->word = "Hide Misspellings"; |
1523 | } | 1573 | } |
@@ -1531,6 +1581,8 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | |||
1531 | suggestionMenuItems.push_back(tempStruct); | 1581 | suggestionMenuItems.push_back(tempStruct); |
1532 | menu->append(suggMenuItem); | 1582 | menu->append(suggMenuItem); |
1533 | } | 1583 | } |
1584 | mLastContextMenuX = x; | ||
1585 | mLastContextMenuY = y; | ||
1534 | menu->buildDrawLabels(); | 1586 | menu->buildDrawLabels(); |
1535 | menu->updateParent(LLMenuGL::sMenuContainer); | 1587 | menu->updateParent(LLMenuGL::sMenuContainer); |
1536 | LLMenuGL::showPopup(this, menu, x, y); | 1588 | LLMenuGL::showPopup(this, menu, x, y); |
@@ -2238,6 +2290,35 @@ void LLTextEditor::spellReplace(SpellMenuBind* spellData) | |||
2238 | needsReflow(); | 2290 | needsReflow(); |
2239 | } | 2291 | } |
2240 | 2292 | ||
2293 | void LLTextEditor::translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length) | ||
2294 | { | ||
2295 | //*TODO: should probably check if the content was modified since the http query | ||
2296 | // was made, so we don't insert text in the wrong place. | ||
2297 | BOOL replace = gSavedSettings.getBOOL("EmeraldTranslateReplace"); | ||
2298 | LLWString wtext = utf8str_to_wstring(replace ? translation : " (" + translation + ")"); | ||
2299 | S32 pos = replace ? orig_start : orig_start + orig_length; | ||
2300 | if (replace) | ||
2301 | { | ||
2302 | remove(orig_start, orig_length, FALSE); | ||
2303 | } | ||
2304 | S32 inserted = insert(pos, wtext, FALSE); | ||
2305 | if (hasSelection()) | ||
2306 | { | ||
2307 | mSelectionStart = llclamp(pos, 0, getLength()); | ||
2308 | mSelectionEnd = llclamp(pos + inserted, mSelectionStart, getLength()); | ||
2309 | } | ||
2310 | setCursorPos(pos + inserted); | ||
2311 | needsReflow(); | ||
2312 | } | ||
2313 | |||
2314 | BOOL LLTextEditor::canTranslate() const | ||
2315 | { | ||
2316 | // if allow_translate="true" in xui, and if other factors permit, we allow it | ||
2317 | S32 pos = getCursorPosFromLocalCoord(mLastContextMenuX, mLastContextMenuY, TRUE); | ||
2318 | bool is_word_part = (pos > -1) && isPartOfWord(mWText[pos]); | ||
2319 | return (mAllowTranslate && !mReadOnly && (is_word_part || hasSelection())); | ||
2320 | } | ||
2321 | |||
2241 | // paste from clipboard | 2322 | // paste from clipboard |
2242 | void LLTextEditor::paste() | 2323 | void LLTextEditor::paste() |
2243 | { | 2324 | { |
@@ -3162,7 +3243,7 @@ void LLTextEditor::drawMisspelled() | |||
3162 | } | 3243 | } |
3163 | } | 3244 | } |
3164 | //draw | 3245 | //draw |
3165 | if (mShowMisspellings) | 3246 | if (glggHunSpell->getSpellCheckHighlight()) |
3166 | { | 3247 | { |
3167 | for (int i = 0; i<(int)misspellLocations.size() ;i++) | 3248 | for (int i = 0; i<(int)misspellLocations.size() ;i++) |
3168 | { | 3249 | { |
@@ -4901,6 +4982,8 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node) | |||
4901 | 4982 | ||
4902 | node->getAttributeBOOL("spell_check", mSpellCheckable); | 4983 | node->getAttributeBOOL("spell_check", mSpellCheckable); |
4903 | 4984 | ||
4985 | node->getAttributeBOOL("allow_translate", mAllowTranslate); | ||
4986 | |||
4904 | LLColor4 color; | 4987 | LLColor4 color; |
4905 | if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) | 4988 | if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) |
4906 | { | 4989 | { |
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/llui/lluixmltags.h b/linden/indra/llui/lluixmltags.h index 4166131..6bbb788 100644 --- a/linden/indra/llui/lluixmltags.h +++ b/linden/indra/llui/lluixmltags.h | |||
@@ -32,100 +32,100 @@ | |||
32 | #ifndef LL_UI_XML_TAGS_H | 32 | #ifndef LL_UI_XML_TAGS_H |
33 | #define LL_UI_XML_TAGS_H | 33 | #define LL_UI_XML_TAGS_H |
34 | 34 | ||
35 | const std::string | 35 | char const* const LL_BUTTON_TAG = "button"; |
36 | LL_BUTTON_TAG("button"), | 36 | char const* const LL_UI_CTRL_LOCATE_TAG = "locate"; |
37 | LL_UI_CTRL_LOCATE_TAG("locate"), | 37 | char const* const LL_PAD_TAG = "pad"; |
38 | LL_PAD_TAG("pad"), | 38 | char const* const LL_CHECK_BOX_CTRL_TAG = "check_box"; |
39 | LL_CHECK_BOX_CTRL_TAG("check_box"), | 39 | char const* const LL_COMBO_BOX_TAG = "combo_box"; |
40 | LL_COMBO_BOX_TAG("combo_box"), | 40 | char const* const LL_DRAG_HANDLE_TOP_TAG = "drag_handle_top"; |
41 | LL_DRAG_HANDLE_TOP_TAG("drag_handle_top"), | 41 | char const* const LL_DRAG_HANDLE_LEFT_TAG = "drag_handle_left"; |
42 | LL_DRAG_HANDLE_LEFT_TAG("drag_handle_left"), | 42 | char const* const LL_FLOATER_TAG = "floater"; |
43 | LL_FLOATER_TAG("floater"), | 43 | char const* const LL_FLOATER_VIEW_TAG = "floater_view"; |
44 | LL_FLOATER_VIEW_TAG("floater_view"), | 44 | char const* const LL_MULTI_FLOATER_TAG = "multi_floater"; |
45 | LL_MULTI_FLOATER_TAG("multi_floater"), | 45 | char const* const LL_ICON_CTRL_TAG = "icon"; |
46 | LL_ICON_CTRL_TAG("icon"), | 46 | char const* const LL_LINE_EDITOR_TAG = "line_editor"; |
47 | LL_LINE_EDITOR_TAG("line_editor"), | 47 | char const* const LL_SEARCH_EDITOR_TAG = "search_editor"; |
48 | LL_SEARCH_EDITOR_TAG("search_editor"), | 48 | char const* const LL_MENU_ITEM_TAG = "menu_item"; |
49 | LL_MENU_ITEM_TAG("menu_item"), | 49 | char const* const LL_MENU_GL_TAG = "menu"; |
50 | LL_MENU_GL_TAG("menu"), | 50 | char const* const LL_MENU_BAR_GL_TAG = "menu_bar"; |
51 | LL_MENU_BAR_GL_TAG("menu_bar"), | 51 | char const* const LL_MENU_HOLDER_GL_TAG = "menu_holder"; |
52 | LL_MENU_HOLDER_GL_TAG("menu_holder"), | 52 | char const* const LL_PANEL_TAG = "panel"; |
53 | LL_PANEL_TAG("panel"), | 53 | char const* const LL_RADIO_GROUP_TAG = "radio_group"; |
54 | LL_RADIO_GROUP_TAG("radio_group"), | 54 | char const* const LL_RESIZE_BAR_TAG = "resize_bar"; |
55 | LL_RESIZE_BAR_TAG("resize_bar"), | 55 | char const* const LL_RESIZE_HANDLE_TAG = "resize_handle"; |
56 | LL_RESIZE_HANDLE_TAG("resize_handle"), | 56 | char const* const LL_SCROLLBAR_TAG = "scrollbar"; |
57 | LL_SCROLLBAR_TAG("scrollbar"), | 57 | char const* const LL_SCROLLABLE_CONTAINER_VIEW_TAG = "scroll_container"; |
58 | LL_SCROLLABLE_CONTAINER_VIEW_TAG("scroll_container"), | 58 | char const* const LL_SCROLL_LIST_CTRL_TAG = "scroll_list"; |
59 | LL_SCROLL_LIST_CTRL_TAG("scroll_list"), | 59 | char const* const LL_SLIDER_CTRL_TAG = "slider"; |
60 | LL_SLIDER_CTRL_TAG("slider"), | 60 | char const* const LL_SLIDER_TAG = "slider_bar"; |
61 | LL_SLIDER_TAG("slider_bar"), | 61 | char const* const LL_MULTI_SLIDER_CTRL_TAG = "multi_slider"; |
62 | LL_MULTI_SLIDER_CTRL_TAG("multi_slider"), | 62 | char const* const LL_MULTI_SLIDER_TAG = "multi_slider_bar"; |
63 | LL_MULTI_SLIDER_TAG("multi_slider_bar"), | 63 | char const* const LL_SPIN_CTRL_TAG = "spinner"; |
64 | LL_SPIN_CTRL_TAG("spinner"), | 64 | char const* const LL_TAB_CONTAINER_COMMON_TAG = "tab_container"; |
65 | LL_TAB_CONTAINER_COMMON_TAG("tab_container"), | 65 | char const* const LL_TEXT_BOX_TAG = "text"; |
66 | LL_TEXT_BOX_TAG("text"), | 66 | char const* const LL_TEXT_EDITOR_TAG = "text_editor"; |
67 | LL_TEXT_EDITOR_TAG("text_editor"), | 67 | char const* const LL_VIEW_BORDER_TAG = "view_border"; |
68 | LL_VIEW_BORDER_TAG("view_border"), | 68 | char const* const LL_COLOR_SWATCH_TAG = "color_swatch"; |
69 | LL_COLOR_SWATCH_TAG("color_swatch"), | 69 | char const* const LL_INVENTORY_PANEL_TAG = "inventory_panel"; |
70 | LL_INVENTORY_PANEL_TAG("inventory_panel"), | 70 | char const* const LL_NAME_EDITOR_TAG = "name_editor"; |
71 | LL_NAME_EDITOR_TAG("name_editor"), | 71 | char const* const LL_NAME_LIST_TAG = "name_list"; |
72 | LL_NAME_LIST_TAG("name_list"), | 72 | char const* const LL_TEXTURE_PICKER_TAG = "texture_picker"; |
73 | LL_TEXTURE_PICKER_TAG("texture_picker"), | 73 | char const* const LL_VOLUME_SLIDER_CTRL_TAG = "volume_slider"; |
74 | LL_VOLUME_SLIDER_CTRL_TAG("volume_slider"), | 74 | char const* const LL_WEB_BROWSER_CTRL_TAG = "web_browser"; |
75 | LL_WEB_BROWSER_CTRL_TAG("web_browser"), | 75 | char const* const LL_STAT_VIEW_TAG = "stat_view"; |
76 | LL_STAT_VIEW_TAG("stat_view"), | 76 | char const* const LL_PROGRESS_VIEW_TAG = "progress_view"; |
77 | LL_PROGRESS_VIEW_TAG("progress_view"), | 77 | char const* const LL_STAT_BAR_TAG = "stat_bar"; |
78 | LL_STAT_BAR_TAG("stat_bar"), | 78 | char const* const LL_STATUS_BAR_TAG = "status_bar"; |
79 | LL_STATUS_BAR_TAG("status_bar"), | 79 | char const* const LL_VIEWER_TEXT_EDITOR_TAG = "viewer_text_editor"; |
80 | LL_VIEWER_TEXT_EDITOR_TAG("viewer_text_editor"), | 80 | char const* const LL_TALK_VIEW_TAG = "talk_view"; |
81 | LL_TALK_VIEW_TAG("talk_view"), | 81 | char const* const LL_COLOR_SWATCH_CTRL_TAG = "color_swatch"; |
82 | LL_COLOR_SWATCH_CTRL_TAG("color_swatch"), | 82 | char const* const LL_GL_TEX_MEM_BAR_TAG = "tex_mem_bar"; |
83 | LL_GL_TEX_MEM_BAR_TAG("tex_mem_bar"), | 83 | char const* const LL_TEXTURE_CTRL_TAG = "texture_picker"; |
84 | LL_TEXTURE_CTRL_TAG("texture_picker"), | 84 | char const* const LL_TEXTURE_VIEW_TAG = "texture_view"; |
85 | LL_TEXTURE_VIEW_TAG("texture_view"), | 85 | char const* const LL_NAME_LIST_CTRL_TAG = "name_list"; |
86 | LL_NAME_LIST_CTRL_TAG("name_list"), | 86 | char const* const LL_STAT_GRAPH_TAG = "stat_graph"; |
87 | LL_STAT_GRAPH_TAG("stat_graph"), | 87 | char const* const LL_DROP_TARGET_TAG = "drop_target"; |
88 | LL_DROP_TARGET_TAG("drop_target"), | 88 | char const* const LL_OVERLAY_BAR_TAG = "overlay_bar"; |
89 | LL_OVERLAY_BAR_TAG("overlay_bar"), | 89 | char const* const LL_NET_MAP_TAG = "net_map"; |
90 | LL_NET_MAP_TAG("net_map"), | 90 | char const* const LL_HUD_VIEW_TAG = "hud_view"; |
91 | LL_HUD_VIEW_TAG("hud_view"), | 91 | char const* const LL_MEMORY_VIEW_TAG = "memory_view"; |
92 | LL_MEMORY_VIEW_TAG("memory_view"), | 92 | char const* const LL_MEDIA_REMOTE_CTRL_TAG = "media_remote"; |
93 | LL_MEDIA_REMOTE_CTRL_TAG("media_remote"), | 93 | char const* const LL_MORPH_VIEW_TAG = "morph_view"; |
94 | LL_MORPH_VIEW_TAG("morph_view"), | 94 | char const* const LL_FRAME_STAT_VIEW_TAG = "frame_stat_view"; |
95 | LL_FRAME_STAT_VIEW_TAG("frame_stat_view"), | 95 | char const* const LL_FOLDER_VIEW_TAG = "folder_view"; |
96 | LL_FOLDER_VIEW_TAG("folder_view"), | 96 | char const* const LL_SNAPSHOT_LIVE_PREVIEW_TAG = "snapshot_preview"; |
97 | LL_SNAPSHOT_LIVE_PREVIEW_TAG("snapshot_preview"), | 97 | char const* const LL_HOVER_VIEW_TAG = "hover_view"; |
98 | LL_HOVER_VIEW_TAG("hover_view"), | 98 | char const* const LL_VELOCITY_BAR_TAG = "velocity_bar"; |
99 | LL_VELOCITY_BAR_TAG("velocity_bar"), | 99 | char const* const LL_PERMISSIONS_VIEW_TAG = "permissions_view"; |
100 | LL_PERMISSIONS_VIEW_TAG("permissions_view"), | 100 | char const* const LL_SCROLLING_PANEL_LIST_TAG = "scrolling_panel_list"; |
101 | LL_SCROLLING_PANEL_LIST_TAG("scrolling_panel_list"), | 101 | char const* const LL_CONTAINER_VIEW_TAG = "container_view"; |
102 | LL_CONTAINER_VIEW_TAG("container_view"), | 102 | char const* const LL_CONSOLE_TAG = "console"; |
103 | LL_CONSOLE_TAG("console"), | 103 | char const* const LL_DEBUG_VIEW_TAG = "debug_view"; |
104 | LL_DEBUG_VIEW_TAG("debug_view"), | 104 | char const* const LL_AUDIOSTATUS_TAG = "audio_status"; |
105 | LL_AUDIOSTATUS_TAG("audio_status"), | 105 | char const* const LL_FAST_TIMER_VIEW_TAG = "fast_timer_view"; |
106 | LL_FAST_TIMER_VIEW_TAG("fast_timer_view"), | 106 | char const* const LL_MENU_ITEM_TEAR_OFF_GL_TAG = "tearoff_menu"; |
107 | LL_MENU_ITEM_TEAR_OFF_GL_TAG("tearoff_menu"), | 107 | char const* const LL_MENU_ITEM_BLANK_GL_TAG = "menu_item_blank"; |
108 | LL_MENU_ITEM_BLANK_GL_TAG("menu_item_blank"), | 108 | char const* const LL_MENU_ITEM_CALL_GL_TAG = "menu_item_call"; |
109 | LL_MENU_ITEM_CALL_GL_TAG("menu_item_call"), | 109 | char const* const LL_MENU_ITEM_CHECK_GL_TAG = "menu_item_check"; |
110 | LL_MENU_ITEM_CHECK_GL_TAG("menu_item_check"), | 110 | char const* const LL_MENU_ITEM_BRANCH_GL_TAG = "menu_item_branch"; |
111 | LL_MENU_ITEM_BRANCH_GL_TAG("menu_item_branch"), | 111 | char const* const LL_MENU_ITEM_BRANCH_DOWN_GL_TAG = "menu_item_branch_down"; |
112 | LL_MENU_ITEM_BRANCH_DOWN_GL_TAG("menu_item_branch_down"), | 112 | char const* const LL_PIE_MENU_BRANCH_TAG = "pie_menu_branch"; |
113 | LL_PIE_MENU_BRANCH_TAG("pie_menu_branch"), | 113 | char const* const LL_PIE_MENU_TAG = "pie_menu"; |
114 | LL_PIE_MENU_TAG("pie_menu"), | 114 | char const* const LL_MENU_ITEM_SEPARATOR_GL_TAG = "menu_item_separator"; |
115 | LL_MENU_ITEM_SEPARATOR_GL_TAG("menu_item_separator"), | 115 | char const* const LL_MENU_ITEM_VERTICAL_SEPARATOR_GL_TAG = "menu_item_vertical_separator"; |
116 | LL_MENU_ITEM_VERTICAL_SEPARATOR_GL_TAG("menu_item_vertical_separator"), | 116 | char const* const LL_ROOT_VIEW_TAG = "root_view"; |
117 | LL_ROOT_VIEW_TAG("root_view"), | 117 | char const* const LL_FOLDER_VIEW_ITEM_TAG = "folder_item"; |
118 | LL_FOLDER_VIEW_ITEM_TAG("folder_item"), | 118 | char const* const LL_FOLDER_VIEW_FOLDER_TAG = "folder"; |
119 | LL_FOLDER_VIEW_FOLDER_TAG("folder"), | 119 | char const* const LL_TEXTURE_BAR_TAG = "texture_bar"; |
120 | LL_TEXTURE_BAR_TAG("texture_bar"), | 120 | char const* const LL_JOYSTICK_SLIDE = "joystick_slide"; |
121 | LL_JOYSTICK_SLIDE("joystick_slide"), | 121 | char const* const LL_JOYSTICK_TURN = "joystick_turn"; |
122 | LL_JOYSTICK_TURN("joystick_turn"), | 122 | char const* const LL_GROUP_DROP_TARGET_TAG = "group_drop_target"; |
123 | LL_GROUP_DROP_TARGET_TAG("group_drop_target"), | 123 | char const* const LL_LAYOUT_STACK_TAG = "layout_stack"; |
124 | LL_LAYOUT_STACK_TAG("layout_stack"), | 124 | char const* const LL_LAYOUT_PANEL_TAG = "layout_panel"; |
125 | LL_LAYOUT_PANEL_TAG("layout_panel"), | 125 | char const* const LL_FLYOUT_BUTTON_TAG = "flyout_button"; |
126 | LL_FLYOUT_BUTTON_TAG("flyout_button"), | 126 | char const* const LL_FLYOUT_BUTTON_ITEM_TAG = "flyout_button_item"; |
127 | LL_FLYOUT_BUTTON_ITEM_TAG("flyout_button_item"), | 127 | char const* const LL_SIMPLE_TEXT_EDITOR_TAG = "simple_text_editor"; |
128 | LL_SIMPLE_TEXT_EDITOR_TAG("simple_text_editor"), | 128 | char const* const LL_RADIO_ITEM_TAG = "radio_item"; |
129 | LL_RADIO_ITEM_TAG("radio_item"), | 129 | char const* const LL_PROGRESS_BAR_TAG = "progress_bar"; |
130 | LL_PROGRESS_BAR_TAG("progress_bar"); | 130 | |
131 | #endif | 131 | #endif |