From 4a625979b8ccb9ffc0c543cdf5fba37008226504 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Thu, 23 Sep 2010 16:56:54 +0200 Subject: Make chat translator ignore non-interesting translations (empty or same as original,) that may result from Google Translate's language autodetec failure. --- linden/indra/newview/llviewermessage.cpp | 45 +++++++++++++++++--------------- linden/indra/newview/llviewermessage.h | 2 +- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index bfd1045..1bab3ff 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -2716,43 +2716,46 @@ void process_decline_callingcard(LLMessageSystem* msg, void**) class ChatTranslationReceiver : public LLTranslate::TranslationReceiver { public : - ChatTranslationReceiver(const std::string &fromLang, const std::string &toLang, LLChat *chat, - const BOOL history) + ChatTranslationReceiver(const std::string &fromLang, const std::string &toLang, const LLChat &chat, + const std::string &orig_mesg, const BOOL history) : LLTranslate::TranslationReceiver(fromLang, toLang), m_chat(chat), + m_origMesg(orig_mesg), m_history(history) { } - static boost::intrusive_ptr build(const std::string &fromLang, const std::string &toLang, LLChat *chat, const BOOL history) + static boost::intrusive_ptr build(const std::string &fromLang, const std::string &toLang, const LLChat &chat, const std::string &orig_mesg, const BOOL history) { - return boost::intrusive_ptr(new ChatTranslationReceiver(fromLang, toLang, chat, history)); + return boost::intrusive_ptr(new ChatTranslationReceiver(fromLang, toLang, chat, orig_mesg, history)); } protected: - void handleResponse(const std::string &translation, const std::string &detectedLanguage) + void handleResponse(const std::string &translation, const std::string &detected_language) { - if (m_toLang != detectedLanguage) - m_chat->mText += " (" + translation + ")"; - - add_floater_chat(*m_chat, m_history); + // filter out non-interesting responeses + if ( !translation.empty() + && (m_toLang != detected_language) + && (LLStringUtil::compareInsensitive(translation, m_origMesg) != 0) ) + { + m_chat.mText += " (" + translation + ")"; + } - delete m_chat; + add_floater_chat(m_chat, m_history); } void handleFailure() { LLTranslate::TranslationReceiver::handleFailure(); - m_chat->mText += " (?)"; + m_chat.mText += " (?)"; - add_floater_chat(*m_chat, m_history); - - delete m_chat; + add_floater_chat(m_chat, m_history); } private: - LLChat *m_chat; + LLChat m_chat; + std::string m_origMesg; const BOOL m_history; }; @@ -2770,9 +2773,9 @@ void add_floater_chat(const LLChat &chat, const BOOL history) } } -void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL history) +void check_translate_chat(const std::string &mesg, const LLChat &chat, const BOOL history) { - const bool translate = LLUI::sConfigGroup->getBOOL("TranslateChat"); + const bool translate = gSavedSettings.getBOOL("TranslateChat"); if (translate && chat.mSourceType != CHAT_SOURCE_SYSTEM) { @@ -2780,9 +2783,8 @@ void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL hist // SVC-4879 const std::string &fromLang = ""; const std::string &toLang = LLTranslate::getTranslateLanguage(); - LLChat *newChat = new LLChat(chat); - LLHTTPClient::ResponderPtr result = ChatTranslationReceiver::build(fromLang, toLang, newChat, history); + LLHTTPClient::ResponderPtr result = ChatTranslationReceiver::build(fromLang, toLang, chat, mesg, history); LLTranslate::translateMessage(result, fromLang, toLang, mesg); } else @@ -2961,8 +2963,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) std::string prefix = mesg.substr(0, 4); if (prefix == "/me " || prefix == "/me'") { - chat.mText = from_name; - chat.mText += mesg.substr(3); + const std::string spacer = mesg.substr(3,1); + mesg = mesg.substr(4); + chat.mText = from_name + spacer + mesg; ircstyle = TRUE; } 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); void process_chat_from_simulator(LLMessageSystem *mesgsys, void **user_data); void add_floater_chat(const LLChat &chat, const BOOL history); -void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL history); +void check_translate_chat(const std::string &mesg, const LLChat &chat, const BOOL history); //void process_agent_to_new_region(LLMessageSystem *mesgsys, void **user_data); void send_agent_update(BOOL force_send, BOOL send_reliable = FALSE); -- cgit v1.1 From cd097fee7848f2e78c0865d0fad7d510a661aa20 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Thu, 23 Sep 2010 19:39:56 +0200 Subject: Fix LLTextEditor context menu translator returning "()" when nothing is selected. New behavior is to translate the word under the mouse if nothing is selected. --- linden/indra/llui/lltexteditor.cpp | 83 +++++++++++++++++++++++++++++++++----- linden/indra/llui/lltexteditor.h | 4 ++ 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index b101588..4bae155 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp @@ -105,21 +105,23 @@ bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = class TextChatTranslationReceiver : public LLTranslate::TranslationReceiver { public : - TextChatTranslationReceiver(const std::string &toLang, LLTextEditor* line): LLTranslate::TranslationReceiver("", toLang), - m_line(line) + TextChatTranslationReceiver(const std::string &toLang, LLTextEditor* line, const S32 start, const S32 len): + LLTranslate::TranslationReceiver("", toLang), + m_line(line), + m_position(start), + m_origLength(len) { } - static boost::intrusive_ptr build(const std::string &toLang,LLTextEditor* line) + static boost::intrusive_ptr build(const std::string &toLang,LLTextEditor* line, const S32 start, const S32 len) { - return boost::intrusive_ptr(new TextChatTranslationReceiver(toLang,line)); + return boost::intrusive_ptr(new TextChatTranslationReceiver(toLang, line, start, len)); } protected: void handleResponse(const std::string &translation, const std::string &detectedLanguage) { - BOOL rep = gSavedSettings.getBOOL("EmeraldTranslateReplace"); - m_line->insertText((rep?"":" (") + translation +(rep?"":")"),rep); + m_line->translationReplace(translation, m_position, m_origLength); } void handleFailure() { @@ -127,6 +129,8 @@ protected: } private: LLTextEditor* m_line; + S32 m_position; + S32 m_origLength; }; /////////////////////////////////////////////////////////////////// @@ -321,6 +325,8 @@ LLTextEditor::LLTextEditor( mMouseDownY(0), mLastSelectionX(-1), mLastSelectionY(-1), + mLastContextMenuX(-1), + mLastContextMenuY(-1), mReflowNeeded(FALSE), mScrollNeeded(FALSE), mSpellCheckable(FALSE), @@ -467,17 +473,36 @@ void LLTextEditor::context_copy(void* data) LLTextEditor* line = (LLTextEditor*)data; if(line)line->copy(); } + void LLTextEditor::translateText(void * data) { SpellMenuBind* t = (SpellMenuBind*)data; LLTextEditor* line = t->origin; const std::string &toLang = t->word;//LLTranslate::getTranslateLanguage(); - LLHTTPClient::ResponderPtr result = TextChatTranslationReceiver::build(toLang,line); - S32 left_pos = llmin( line->mSelectionStart, line->mSelectionEnd ); - S32 length = abs( line->mSelectionStart - line->mSelectionEnd ); - LLTranslate::translateMessage(result,"", toLang, line->getText().substr(left_pos, length)); + bool has_text = false; + S32 start, length; + if (line->hasSelection()) + { + // translate selection + start = llmin(line->mSelectionStart, line->mSelectionEnd); + length = abs(line->mSelectionEnd - line->mSelectionStart); + has_text = length > 0; + } + else + { + // translate one word as click position + S32 at = line->getCursorPosFromLocalCoord(line->mLastContextMenuX, line->mLastContextMenuY, TRUE); + has_text = line->getWordBoundriesAt(at, &start, &length); + } + + if (has_text) + { + LLHTTPClient::ResponderPtr result = TextChatTranslationReceiver::build(toLang, line, start, length); + LLTranslate::translateMessage(result,"", toLang, line->getText().substr(start, length)); + } } + void LLTextEditor::spell_correct(void* data) { SpellMenuBind* tempBind = (SpellMenuBind*)data; @@ -947,6 +972,26 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const return cursorPos; } +BOOL LLTextEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const +{ + S32 pos = at; + if (isPartOfWord(mWText[pos])) + { + while ( (pos > 0) && isPartOfWord(mWText[pos - 1]) ) + { + pos--; + } + *word_begin = pos; + while ( (pos < getLength()) && isPartOfWord(mWText[pos]) ) + { + pos++; + } + *word_length = pos - *word_begin; + return TRUE; + } + return FALSE; +} + S32 LLTextEditor::getLineStart( S32 line ) const { S32 num_lines = getLineCount(); @@ -1531,6 +1576,8 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) suggestionMenuItems.push_back(tempStruct); menu->append(suggMenuItem); } + mLastContextMenuX = x; + mLastContextMenuY = y; menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); LLMenuGL::showPopup(this, menu, x, y); @@ -2238,6 +2285,22 @@ void LLTextEditor::spellReplace(SpellMenuBind* spellData) needsReflow(); } +void LLTextEditor::translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length) +{ + //*TODO: should probably check if the content was modified since the http query + // was made, so we don't insert text in the wrong place. + BOOL replace = gSavedSettings.getBOOL("EmeraldTranslateReplace"); + LLWString wtext = utf8str_to_wstring(replace ? translation : " (" + translation + ")"); + S32 pos = replace ? orig_start : orig_start + orig_length; + if (replace) + { + remove(orig_start, orig_length, FALSE); + } + insert(pos, wtext, FALSE); + setCursorPos(pos + wtext.length()); + needsReflow(); +} + // paste from clipboard void LLTextEditor::paste() { diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index 57a6bbd..f6669c4 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h @@ -136,6 +136,7 @@ public: virtual BOOL canPaste() const; virtual void spellReplace(SpellMenuBind* spellData); + virtual void translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length); virtual void updatePrimary(); virtual void copyPrimary(); @@ -352,6 +353,7 @@ public: S32 prevWordPos(S32 cursorPos) const; S32 nextWordPos(S32 cursorPos) const; + BOOL getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const; S32 getLineCount() const { return mLineStartList.size(); } S32 getLineStart( S32 line ) const; @@ -568,6 +570,8 @@ private: //to keep track of what we have to remove before showing menu std::vector suggestionMenuItems; + S32 mLastContextMenuX; + S32 mLastContextMenuY; line_list_t mLineStartList; BOOL mReflowNeeded; -- cgit v1.1 From f6f5603b946a56059987071b7151a1c2e64c45d5 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Fri, 24 Sep 2010 02:29:58 +0200 Subject: Fix LLLineEditor context menu translator returning "()" when nothing is selected. New behavior is to translate the word under the mouse if nothing is selected. --- linden/indra/llui/lllineeditor.cpp | 90 +++++++++++++++++++++++++++++++++----- linden/indra/llui/lllineeditor.h | 3 ++ 2 files changed, 81 insertions(+), 12 deletions(-) diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 66ef4c6..27a1d50 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -96,23 +96,23 @@ static LLRegisterWidget r1("line_editor"); class LineChatTranslationReceiver : public LLTranslate::TranslationReceiver { public : - LineChatTranslationReceiver(const std::string &toLang, LLLineEditor* line): LLTranslate::TranslationReceiver("", toLang), - m_line(line) + LineChatTranslationReceiver(const std::string &toLang, LLLineEditor* line, const S32 start, const S32 len): + LLTranslate::TranslationReceiver("", toLang), + m_line(line), + m_position(start), + m_origLength(len) { } - static boost::intrusive_ptr build(const std::string &toLang,LLLineEditor* line) + static boost::intrusive_ptr build(const std::string &toLang,LLLineEditor* line, const S32 start, const S32 len) { - return boost::intrusive_ptr(new LineChatTranslationReceiver(toLang,line)); + return boost::intrusive_ptr(new LineChatTranslationReceiver(toLang, line, start, len)); } protected: void handleResponse(const std::string &translation, const std::string &detectedLanguage) { - static BOOL* rep = rebind_llcontrol("EmeraldTranslateReplace", &gSavedSettings, true); - if(*rep) - m_line->deleteSelection(); - m_line->insert(((*rep)?"":" (") + translation + ((*rep)?"":")"),m_line->getCursor()); + m_line->translationReplace(translation, m_position, m_origLength); } void handleFailure() { @@ -120,6 +120,8 @@ protected: } private: LLLineEditor* m_line; + S32 m_position; + S32 m_origLength; }; LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, @@ -151,6 +153,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, mLastSelectionY(-1), mLastSelectionStart(-1), mLastSelectionEnd(-1), + mLastContextMenuX(-1), mPrevalidateFunc( prevalidate_func ), mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ), mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ), @@ -539,16 +542,36 @@ void LLLineEditor::spell_correct(void* data) } } + void LLLineEditor::translateText(void * data) { SpellMenuBind* t = (SpellMenuBind*)data; LLLineEditor* line = t->origin; const std::string &toLang = t->word;//LLTranslate::getTranslateLanguage(); - LLHTTPClient::ResponderPtr result = LineChatTranslationReceiver::build(toLang,line); - S32 left_pos = llmin( line->mSelectionStart, line->mSelectionEnd ); - S32 length = abs( line->mSelectionStart - line->mSelectionEnd ); - LLTranslate::translateMessage(result,"", toLang, line->mText.getString().substr(left_pos, length)); + + bool has_text = false; + S32 start, length; + if (line->hasSelection()) + { + // translate selection + start = llmin(line->mSelectionStart, line->mSelectionEnd); + length = abs(line->mSelectionEnd - line->mSelectionStart); + has_text = length > 0; + } + else + { + // translate one word at click position + S32 at = line->calculateCursorFromMouse(line->mLastContextMenuX); + has_text = line->getWordBoundriesAt(at, &start, &length); + } + + if (has_text) + { + LLHTTPClient::ResponderPtr result = LineChatTranslationReceiver::build(toLang, line, start, length); + LLTranslate::translateMessage(result,"", toLang, line->getText().substr(start, length)); + } } + void LLLineEditor::spell_show(void * data) { SpellMenuBind* tempBind = (SpellMenuBind*)data; @@ -836,6 +859,7 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) menu->append(suggMenuItem); } + mLastContextMenuX = x; menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); LLMenuGL::showPopup(this, menu, x, y); @@ -1152,6 +1176,26 @@ S32 LLLineEditor::nextWordPos(S32 cursorPos) const return cursorPos; } +BOOL LLLineEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const +{ + const LLWString& wtext = mText.getWString(); + S32 pos = at; + if (LLTextEditor::isPartOfWord(wtext[pos])) + { + while ( (pos > 0) && LLTextEditor::isPartOfWord(wtext[pos - 1]) ) + { + pos--; + } + *word_begin = pos; + while ( (pos < getLength()) && LLTextEditor::isPartOfWord(wtext[pos]) ) + { + pos++; + } + *word_length = pos - *word_begin; + return TRUE; + } + return FALSE; +} BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) { @@ -1315,6 +1359,28 @@ void LLLineEditor::spellReplace(SpellMenuBind* spellData) } + +void LLLineEditor::translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length) +{ + //*TODO: should probably check if the content was modified since the http query + // was made, so we don't insert text in the wrong place. + BOOL replace = gSavedSettings.getBOOL("EmeraldTranslateReplace"); + std::string text = replace ? translation : " (" + translation + ")"; + S32 pos = replace ? orig_start : orig_start + orig_length; + if (replace) + { + mText.erase(orig_start, orig_length); + } + insert(text, pos); + + if (hasSelection()) + { + mSelectionStart = pos; + mSelectionEnd = pos + text.length(); + } + setCursor(pos + text.length()); +} + void LLLineEditor::insert(std::string what, S32 wher) { LLLineEditorRollback rollback(this); diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index 147b232..af37f62 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h @@ -107,6 +107,7 @@ public: }; virtual void spellReplace(SpellMenuBind* spellData); + virtual void translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length); virtual void insert(std::string what,S32 wher); // LLEditMenuHandler overrides @@ -215,6 +216,7 @@ public: // get the cursor position of the beginning/end of the prev/next word in the text S32 prevWordPos(S32 cursorPos) const; S32 nextWordPos(S32 cursorPos) const; + BOOL getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const; BOOL hasSelection() const { return (mSelectionStart != mSelectionEnd); } void startSelection(); @@ -298,6 +300,7 @@ protected: LLFrameTimer mSpellTimer; //to keep track of what we have to remove before showing menu std::vector suggestionMenuItems; + S32 mLastContextMenuX; // line history support: BOOL mHaveHistory; // flag for enabled line history -- cgit v1.1 From 6cd906519bf090dff532b3cf4d206fd1a25c6504 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Sat, 25 Sep 2010 01:14:51 +0200 Subject: More LLLineEditor context translator bugfixes: - Use LLWString when doing size calculations (potential crashes and misplaced text) - Weird selection range after translating selected text. --- linden/indra/llui/lllineeditor.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 27a1d50..5f2a314 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -567,8 +567,9 @@ void LLLineEditor::translateText(void * data) if (has_text) { + std::string to_translate = wstring_to_utf8str(line->getWText().substr(start, length)); LLHTTPClient::ResponderPtr result = LineChatTranslationReceiver::build(toLang, line, start, length); - LLTranslate::translateMessage(result,"", toLang, line->getText().substr(start, length)); + LLTranslate::translateMessage(result,"", toLang, to_translate); } } @@ -1133,13 +1134,11 @@ void LLLineEditor::setSelection(S32 start, S32 end) { S32 len = mText.length(); - mIsSelecting = TRUE; - // JC, yes, this seems odd, but I think you have to presume a // selection dragged from the end towards the start. mSelectionStart = llclamp(end, 0, len); mSelectionEnd = llclamp(start, 0, len); - setCursor(start); + setCursor(end); } void LLLineEditor::setDrawAsterixes(BOOL b) @@ -1187,7 +1186,7 @@ BOOL LLLineEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_l pos--; } *word_begin = pos; - while ( (pos < getLength()) && LLTextEditor::isPartOfWord(wtext[pos]) ) + while ( (pos < wtext.length()) && LLTextEditor::isPartOfWord(wtext[pos]) ) { pos++; } @@ -1373,12 +1372,12 @@ void LLLineEditor::translationReplace(const std::string &translation, const S32 } insert(text, pos); + S32 text_wlen = utf8str_to_wstring(text).length(); if (hasSelection()) { - mSelectionStart = pos; - mSelectionEnd = pos + text.length(); + setSelection(pos, pos + text_wlen); } - setCursor(pos + text.length()); + setCursor(pos + text_wlen); } void LLLineEditor::insert(std::string what, S32 wher) -- cgit v1.1 From 8f30fb06d1361d7d74f018d5bbaf5e82b846d8a4 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Sat, 25 Sep 2010 04:04:26 +0200 Subject: LLLineEditor context translator: re-select text properly. --- linden/indra/llui/lllineeditor.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 5f2a314..503a1bd 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -1134,10 +1134,8 @@ void LLLineEditor::setSelection(S32 start, S32 end) { S32 len = mText.length(); - // JC, yes, this seems odd, but I think you have to presume a - // selection dragged from the end towards the start. - mSelectionStart = llclamp(end, 0, len); - mSelectionEnd = llclamp(start, 0, len); + mSelectionStart = llclamp(start, 0, len); + mSelectionEnd = llclamp(end, 0, len); setCursor(end); } -- cgit v1.1 From f5006e8a2f34afa390f0bbcf0f6af15218cf4105 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Sat, 25 Sep 2010 12:58:56 +0200 Subject: LLLineEditor context translator: - Added a xui attribute "allow_translate", default to off (not enabled in any xml file yet.) - Only show translate menu if clicked on a word, or something is selected. --- linden/indra/llui/lllineeditor.cpp | 35 ++++++++++++++++------------------- linden/indra/llui/lllineeditor.h | 2 ++ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 503a1bd..05966d6 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -175,7 +175,8 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, mImage( sImage ), mReplaceNewlinesWithSpaces( TRUE ), mSpellCheckable( FALSE ), - mShowMisspellings(FALSE) + mShowMisspellings(FALSE), + mAllowTranslate(FALSE) { llassert( max_length_bytes > 0 ); @@ -762,7 +763,8 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) //setCursorAtLocalPos( x); S32 wordStart = 0; - S32 wordEnd = calculateCursorFromMouse(x); + S32 wordEnd = 0; + S32 pos = calculateCursorFromMouse(x); LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu) @@ -785,29 +787,19 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) } suggestionMenuItems.clear(); - menu->setItemVisible("Translate To", !mReadOnly); - menu->setItemVisible("Transep", !mReadOnly); + bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordEnd); + // allow_translate="true" in xui + bool can_translate = mAllowTranslate && !mReadOnly && (is_word_part || hasSelection()); + menu->setItemVisible("Translate To", can_translate); + menu->setItemVisible("Transep", can_translate); // spell_check="true" in xui if (!mReadOnly && mSpellCheckable) { - const LLWString& text = mText.getWString(); - // search for word matches - if (LLTextEditor::isPartOfWord(text[wordEnd])) + if (is_word_part) { - // Select word the cursor is over - while ((wordEnd > 0) && LLTextEditor::isPartOfWord(text[wordEnd-1])) - { - wordEnd--; - } - wordStart = wordEnd; - //startSelection(); - - while ((wordEnd < (S32)text.length()) && LLTextEditor::isPartOfWord( text[wordEnd] ) ) - { - wordEnd++; - } + const LLWString& text = mText.getWString(); std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart)); if (!glggHunSpell->isSpelledRight(selectedWord)) @@ -2893,6 +2885,11 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory { line_editor->setSpellCheckable(spell_checking); } + BOOL allow_translate = FALSE; + if (node->getAttributeBOOL("allow_translate", allow_translate)) + { + line_editor->setAllowTranslate(allow_translate); + } line_editor->setColorParameters(node); diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index af37f62..0ad415a 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h @@ -200,6 +200,7 @@ public: void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; } void setSpellCheckable(BOOL b) { mSpellCheckable = b; } + void setAllowTranslate(BOOL b) { mAllowTranslate = b; } const LLColor4& getFgColor() const { return mFgColor; } const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor; } @@ -301,6 +302,7 @@ protected: //to keep track of what we have to remove before showing menu std::vector suggestionMenuItems; S32 mLastContextMenuX; + BOOL mAllowTranslate; // set in xui as "allow_translate". // line history support: BOOL mHaveHistory; // flag for enabled line history -- cgit v1.1 From 81a3df503aece6b46e1efbdb7e274253cb898660 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Sat, 25 Sep 2010 15:00:50 +0200 Subject: LLTextEditor context translator: - Added a xui attribute "allow_translate", default to off (not enabled in any xml file yet.) - Only show translate menu if clicked on a word, or something is selected. --- linden/indra/llui/lltexteditor.cpp | 34 +++++++++++++++------------------- linden/indra/llui/lltexteditor.h | 1 + 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index 4bae155..adf0260 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp @@ -330,7 +330,8 @@ LLTextEditor::LLTextEditor( mReflowNeeded(FALSE), mScrollNeeded(FALSE), mSpellCheckable(FALSE), - mShowMisspellings(FALSE) + mShowMisspellings(FALSE), + mAllowTranslate(FALSE) { mSourceID.generate(); @@ -1484,7 +1485,8 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) //setCursorAtLocalPos( x, y, TRUE ); S32 wordStart = 0; - S32 wordEnd = getCursorPosFromLocalCoord(x,y,TRUE); + S32 wordEnd = 0; + S32 pos = getCursorPosFromLocalCoord(x,y,TRUE); LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu) @@ -1503,29 +1505,21 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) } suggestionMenuItems.clear(); - menu->setItemVisible("Translate To", !mReadOnly); - menu->setItemVisible("Transep", !mReadOnly); + bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordEnd); + + // allow_translate="true" in xui + bool can_translate = mAllowTranslate && !mReadOnly && (is_word_part || hasSelection()); + menu->setItemVisible("Translate To", can_translate); + menu->setItemVisible("Transep", can_translate); // spell_check="true" in xui if (!mReadOnly && mSpellCheckable) { - const LLWString &text = mWText; - - if (isPartOfWord(text[wordEnd]) && !mReadOnly) + if (is_word_part) { - // Select word the cursor is over - while ((wordEnd > 0) && isPartOfWord(text[wordEnd-1])) - { - wordEnd--; - } - wordStart = wordEnd; - //startSelection(); - - while ((wordEnd < (S32)text.length()) && isPartOfWord( text[wordEnd] ) ) - { - wordEnd++; - } + const LLWString &text = mWText; std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart)); + if (!glggHunSpell->isSpelledRight(selectedWord)) { //misspelled word here, and you have just right clicked on it! @@ -4964,6 +4958,8 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node) node->getAttributeBOOL("spell_check", mSpellCheckable); + node->getAttributeBOOL("allow_translate", mAllowTranslate); + LLColor4 color; if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) { diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index f6669c4..3269e17 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h @@ -530,6 +530,7 @@ private: std::vector misspellLocations; // where all the mispelled words are BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field BOOL mShowMisspellings; // show misspellings as highlighted (initialized in the ctor) + BOOL mAllowTranslate; // set in xui as "allow_translate". S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes -- cgit v1.1 From 2760d30363716b8d469134d197a9874eccea6aa3 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Sat, 25 Sep 2010 16:14:11 +0200 Subject: LLTextEditor context translator: set selection after translation. --- linden/indra/llui/lltexteditor.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index adf0260..d59eed6 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp @@ -499,8 +499,9 @@ void LLTextEditor::translateText(void * data) if (has_text) { + const std::string to_translate = wstring_to_utf8str(line->getWText().substr(start, length)); LLHTTPClient::ResponderPtr result = TextChatTranslationReceiver::build(toLang, line, start, length); - LLTranslate::translateMessage(result,"", toLang, line->getText().substr(start, length)); + LLTranslate::translateMessage(result,"", toLang, to_translate); } } @@ -2290,8 +2291,13 @@ void LLTextEditor::translationReplace(const std::string &translation, const S32 { remove(orig_start, orig_length, FALSE); } - insert(pos, wtext, FALSE); - setCursorPos(pos + wtext.length()); + S32 inserted = insert(pos, wtext, FALSE); + if (hasSelection()) + { + mSelectionStart = llclamp(pos, 0, getLength()); + mSelectionEnd = llclamp(pos + inserted, mSelectionStart, getLength()); + } + setCursorPos(pos + inserted); needsReflow(); } -- cgit v1.1 From 702b44426e036495c5568e7422e8cd77a46f1966 Mon Sep 17 00:00:00 2001 From: thickbrick Date: Sat, 25 Sep 2010 16:18:20 +0200 Subject: Context translator: default to enabled. Set the default of the xui attribute "allow_translate" to true, and add allow_translate="false" to panel_login.xml. This probably needs to be disabled in other places as well. --- linden/indra/llui/lllineeditor.cpp | 4 ++-- linden/indra/llui/lltexteditor.cpp | 2 +- linden/indra/newview/skins/default/xui/en-us/panel_login.xml | 9 ++++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 05966d6..8d88ce9 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -176,7 +176,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, mReplaceNewlinesWithSpaces( TRUE ), mSpellCheckable( FALSE ), mShowMisspellings(FALSE), - mAllowTranslate(FALSE) + mAllowTranslate(TRUE) { llassert( max_length_bytes > 0 ); @@ -2885,7 +2885,7 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory { line_editor->setSpellCheckable(spell_checking); } - BOOL allow_translate = FALSE; + BOOL allow_translate = TRUE; if (node->getAttributeBOOL("allow_translate", allow_translate)) { line_editor->setAllowTranslate(allow_translate); diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index d59eed6..5ee94c8 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp @@ -331,7 +331,7 @@ LLTextEditor::LLTextEditor( mScrollNeeded(FALSE), mSpellCheckable(FALSE), mShowMisspellings(FALSE), - mAllowTranslate(FALSE) + mAllowTranslate(TRUE) { mSourceID.generate(); 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 @@ bevel_style="in" border_style="line" border_thickness="1" max_length="31" mouse_opaque="true" handle_edit_keys_directly="true" - select_all_on_focus_received="true" /> + select_all_on_focus_received="true" + allow_translate="false" /> @@ -77,7 +78,8 @@ bevel_style="in" border_style="line" border_thickness="1" max_length="31" mouse_opaque="true" handle_edit_keys_directly="true" - select_all_on_focus_received="true" /> + select_all_on_focus_received="true" + allow_translate="false" /> @@ -96,7 +98,8 @@ bevel_style="in" border_style="line" border_thickness="1" max_length="16" mouse_opaque="true" handle_edit_keys_directly="true" - select_all_on_focus_received="true" /> + select_all_on_focus_received="true" + allow_translate="false" /> append(new LLMenuItemCallGL("Paste", context_paste, NULL, this)); menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this)); menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this)); - menu->appendSeparator("transep"); + menu->appendSeparator("Transep"); LLMenuGL* translatemenu = new LLMenuGL("Translate To"); translatemenu->setCanTearOff(FALSE); SpellMenuBind* t=new SpellMenuBind;t->origin=this;t->word="en"; -- cgit v1.1 From 13b1fd24af265af8eb14585121958bf1e4bc89fd Mon Sep 17 00:00:00 2001 From: thickbrick Date: Tue, 28 Sep 2010 18:06:43 +0200 Subject: Context menu translator: - Don't hide the translate menu, instead only enable the options that make sense in the context (translate languages, copy/paste/etc.) - Made highlighting misspellings a global option, with immediate effect. - Convert newview/lgghunspell_wrapper.cpp to UTF-8. --- linden/indra/llui/lllineeditor.cpp | 127 +++++++++++++++++---------- linden/indra/llui/lllineeditor.h | 19 ++-- linden/indra/llui/lltexteditor.cpp | 125 ++++++++++++++++---------- linden/indra/llui/lltexteditor.h | 12 ++- linden/indra/newview/lgghunspell_wrapper.cpp | 18 ++-- linden/indra/newview/lgghunspell_wrapper.h | 4 +- 6 files changed, 189 insertions(+), 116 deletions(-) diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 8d88ce9..49fe3be 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -175,7 +175,6 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, mImage( sImage ), mReplaceNewlinesWithSpaces( TRUE ), mSpellCheckable( FALSE ), - mShowMisspellings(FALSE), mAllowTranslate(TRUE) { llassert( max_length_bytes > 0 ); @@ -215,12 +214,6 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, } mImage = sImage; - // in other words, highlighting requires a restart - if (glggHunSpell->getSpellCheckHighlight()) - { - mShowMisspellings = TRUE; - } - // make the popup menu available //LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view); LLMenuGL* menu = new LLMenuGL("wot"); @@ -228,46 +221,49 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, { menu = new LLMenuGL(LLStringUtil::null); }*/ - menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this)); - menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this)); - menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this)); - menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this)); - menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this)); + + menu->append(new LLMenuItemCallGL("Cut", context_cut, context_enable_cut, this)); + menu->append(new LLMenuItemCallGL("Copy", context_copy, context_enable_copy, this)); + menu->append(new LLMenuItemCallGL("Paste", context_paste, context_enable_paste, this)); + menu->append(new LLMenuItemCallGL("Delete", context_delete, context_enable_delete, this)); + menu->append(new LLMenuItemCallGL("Select All", context_selectall, context_enable_selectall, this)); + menu->appendSeparator("Transep"); LLMenuGL* translatemenu = new LLMenuGL("Translate To"); translatemenu->setCanTearOff(FALSE); SpellMenuBind* t=new SpellMenuBind;t->origin=this;t->word="en"; - translatemenu->append(new LLMenuItemCallGL("English",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("English", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="da"; - translatemenu->append(new LLMenuItemCallGL("Danish",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Danish", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="de"; - translatemenu->append(new LLMenuItemCallGL("Deutsch(German)",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Deutsch(German)", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="es"; - translatemenu->append(new LLMenuItemCallGL("Spanish",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Spanish", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="fr"; - translatemenu->append(new LLMenuItemCallGL("French",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("French", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="it"; - translatemenu->append(new LLMenuItemCallGL("Italian",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Italian", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="hu"; - translatemenu->append(new LLMenuItemCallGL("Hungarian",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Hungarian", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="nl"; - translatemenu->append(new LLMenuItemCallGL("Dutch",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Dutch", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="pl"; - translatemenu->append(new LLMenuItemCallGL("Polish",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Polish", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="pt"; - translatemenu->append(new LLMenuItemCallGL("Portugese",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Portugese", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="ru"; - translatemenu->append(new LLMenuItemCallGL("Russian",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Russian", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="tr"; - translatemenu->append(new LLMenuItemCallGL("Turkish",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Turkish", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="uk"; - translatemenu->append(new LLMenuItemCallGL("Ukrainian",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Ukrainian", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="zh"; - translatemenu->append(new LLMenuItemCallGL("Chinese",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Chinese", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="ja"; - translatemenu->append(new LLMenuItemCallGL("Japanese",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Japanese", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="ko"; - translatemenu->append(new LLMenuItemCallGL("Korean",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Korean", context_translate, context_enable_translate, t)); + menu->appendMenu(translatemenu); menu->appendSeparator("Spelsep"); //menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); @@ -443,7 +439,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) // Picks a new cursor position based on the actual screen size of text being drawn. -S32 LLLineEditor::calculateCursorFromMouse( S32 local_mouse_x ) +S32 LLLineEditor::calculateCursorFromMouse( S32 local_mouse_x ) const { const llwchar* wtext = mText.getWString().c_str(); LLWString asterix_text; @@ -521,17 +517,30 @@ void LLLineEditor::deselect() mIsSelecting = FALSE; } +BOOL LLLineEditor::context_enable_cut(void* data) +{ + LLLineEditor* line = (LLLineEditor*)data; + return (line && line->canCut()); +} void LLLineEditor::context_cut(void* data) { LLLineEditor* line = (LLLineEditor*)data; if(line)line->cut(); } + +BOOL LLLineEditor::context_enable_copy(void* data) +{ + LLLineEditor* line = (LLLineEditor*)data; + return (line &&line->canCopy()); +} + void LLLineEditor::context_copy(void* data) { LLLineEditor* line = (LLLineEditor*)data; if(line)line->copy(); } + void LLLineEditor::spell_correct(void* data) { SpellMenuBind* tempBind = (SpellMenuBind*)data; @@ -544,7 +553,13 @@ void LLLineEditor::spell_correct(void* data) } } -void LLLineEditor::translateText(void * data) +BOOL LLLineEditor::context_enable_translate(void* data) +{ + SpellMenuBind* t = (SpellMenuBind*)data; + return (t && t->origin && t->origin->canTranslate()); +} + +void LLLineEditor::context_translate(void * data) { SpellMenuBind* t = (SpellMenuBind*)data; LLLineEditor* line = t->origin; @@ -579,16 +594,10 @@ void LLLineEditor::spell_show(void * data) SpellMenuBind* tempBind = (SpellMenuBind*)data; LLLineEditor* line = tempBind->origin; - if( tempBind && line) + if (tempBind && line) { - if (tempBind->word == "Show Misspellings") - { - line->mShowMisspellings = TRUE; - } - else - { - line->mShowMisspellings = FALSE; - } + BOOL show = (tempBind->word == "Show Misspellings"); + glggHunSpell->setSpellCheckHighlight(show); } } @@ -648,18 +657,36 @@ void LLLineEditor::spell_add(void* data) } } +BOOL LLLineEditor::context_enable_paste(void* data) +{ + LLLineEditor* line = (LLLineEditor*)data; + return (line && line->canPaste()); +} + void LLLineEditor::context_paste(void* data) { LLLineEditor* line = (LLLineEditor*)data; if(line)line->paste(); } +BOOL LLLineEditor::context_enable_delete(void* data) +{ + LLLineEditor* line = (LLLineEditor*)data; + return (line && line->canDoDelete()); +} + void LLLineEditor::context_delete(void* data) { LLLineEditor* line = (LLLineEditor*)data; if(line)line->doDelete(); } +BOOL LLLineEditor::context_enable_selectall(void* data) +{ + LLLineEditor* line = (LLLineEditor*)data; + return (line && line->canSelectAll()); +} + void LLLineEditor::context_selectall(void* data) { LLLineEditor* line = (LLLineEditor*)data; @@ -787,16 +814,12 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) } suggestionMenuItems.clear(); - bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordEnd); - // allow_translate="true" in xui - bool can_translate = mAllowTranslate && !mReadOnly && (is_word_part || hasSelection()); - menu->setItemVisible("Translate To", can_translate); - menu->setItemVisible("Transep", can_translate); - // spell_check="true" in xui + menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable); if (!mReadOnly && mSpellCheckable) { // search for word matches + bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordEnd); if (is_word_part) { const LLWString& text = mText.getWString(); @@ -806,7 +829,6 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) { //misspelled word here, and you have just right clicked on it! std::vector suggs = glggHunSpell->getSuggestionList(selectedWord); - //menu->setItemVisible("Transep",(suggs.size()>0)); for (int i = 0; i<(int)suggs.size() ;i++) { @@ -837,7 +859,7 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) SpellMenuBind * tempStruct = new SpellMenuBind; tempStruct->origin = this; - if (mShowMisspellings) + if (glggHunSpell->getSpellCheckHighlight()) { tempStruct->word = "Hide Misspellings"; } @@ -1370,6 +1392,15 @@ void LLLineEditor::translationReplace(const std::string &translation, const S32 setCursor(pos + text_wlen); } +BOOL LLLineEditor::canTranslate() const +{ + // if allow_translate="true" in xui, and if other factors permit, we allow it + S32 pos = calculateCursorFromMouse(mLastContextMenuX); + const LLWString& wtext = getWText(); + bool is_word_part = (pos > -1) && LLTextEditor::isPartOfWord(wtext[pos]); + return (mAllowTranslate && !mReadOnly && (is_word_part || hasSelection())); +} + void LLLineEditor::insert(std::string what, S32 wher) { LLLineEditorRollback rollback(this); @@ -1980,7 +2011,7 @@ void LLLineEditor::drawMisspelled(LLRect background) } } - if (mShowMisspellings) + if (glggHunSpell->getSpellCheckHighlight()) { for (int i =0; i<(int)misspellLocations.size(); i++) { diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index 0ad415a..f9e0621 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h @@ -108,6 +108,7 @@ public: virtual void spellReplace(SpellMenuBind* spellData); virtual void translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length); + virtual BOOL canTranslate() const; virtual void insert(std::string what,S32 wher); // LLEditMenuHandler overrides @@ -134,15 +135,22 @@ public: virtual void deselect(); virtual BOOL canDeselect() const; + static BOOL context_enable_cut(void* data); static void context_cut(void* data); + static BOOL context_enable_copy(void* data); static void context_copy(void* data); - static void spell_correct(void* data); - static void spell_show(void* data); - static void translateText(void * data); - static void spell_add(void* data); + static BOOL context_enable_paste(void* data); static void context_paste(void* data); + static BOOL context_enable_delete(void* data); static void context_delete(void* data); + static BOOL context_enable_selectall(void* data); static void context_selectall(void* data); + static BOOL context_enable_translate(void * data); + static void context_translate(void * data); + static void spell_correct(void* data); + static void spell_show(void* data); + static void spell_add(void* data); + std::vector getMisspelledWordsPositions(); // view overrides virtual void draw(); @@ -264,7 +272,7 @@ private: void removeChar(); void addChar(const llwchar c); void setCursorAtLocalPos(S32 local_mouse_x); - S32 calculateCursorFromMouse(S32 local_mouse_x); + S32 calculateCursorFromMouse(S32 local_mouse_x) const; S32 findPixelNearestPos(S32 cursor_offset = 0) const; void reportBadKeystroke(); BOOL handleSpecialKey(KEY key, MASK mask); @@ -297,7 +305,6 @@ protected: S32 mStartSpellHere; // the position of the first char on the screen, stored so we know when to update S32 mEndSpellHere; // the location of the last char on the screen BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field - BOOL mShowMisspellings; // show misspellings as highlighted (initialized in the ctor) LLFrameTimer mSpellTimer; //to keep track of what we have to remove before showing menu std::vector suggestionMenuItems; diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index e2335c9..8dcb014 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp @@ -330,7 +330,6 @@ LLTextEditor::LLTextEditor( mReflowNeeded(FALSE), mScrollNeeded(FALSE), mSpellCheckable(FALSE), - mShowMisspellings(FALSE), mAllowTranslate(TRUE) { mSourceID.generate(); @@ -384,12 +383,6 @@ LLTextEditor::LLTextEditor( mParseHTML=FALSE; mHTML.clear(); - // in other words, highlighting requires a restart - if (glggHunSpell->getSpellCheckHighlight()) - { - mShowMisspellings = TRUE; - } - // make the popup menu available //LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view); LLMenuGL* menu = new LLMenuGL("wot"); @@ -397,46 +390,46 @@ LLTextEditor::LLTextEditor( { menu = new LLMenuGL(LLStringUtil::null); }*/ - menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this)); - menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this)); - menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this)); - menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this)); - menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this)); + menu->append(new LLMenuItemCallGL("Cut", context_cut, context_enable_cut, this)); + menu->append(new LLMenuItemCallGL("Copy", context_copy, context_enable_copy, this)); + menu->append(new LLMenuItemCallGL("Paste", context_paste, context_enable_paste, this)); + menu->append(new LLMenuItemCallGL("Delete", context_delete, context_enable_delete, this)); + menu->append(new LLMenuItemCallGL("Select All", context_selectall, context_enable_selectall, this)); menu->appendSeparator("Transep"); LLMenuGL* translatemenu = new LLMenuGL("Translate To"); translatemenu->setCanTearOff(FALSE); SpellMenuBind* t=new SpellMenuBind;t->origin=this;t->word="en"; - translatemenu->append(new LLMenuItemCallGL("English",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("English", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="da"; - translatemenu->append(new LLMenuItemCallGL("Danish",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Danish", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="de"; - translatemenu->append(new LLMenuItemCallGL("Deutsch(German)",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Deutsch(German)", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="es"; - translatemenu->append(new LLMenuItemCallGL("Spanish",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Spanish", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="fr"; - translatemenu->append(new LLMenuItemCallGL("French",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("French", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="it"; - translatemenu->append(new LLMenuItemCallGL("Italian",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Italian", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="hu"; - translatemenu->append(new LLMenuItemCallGL("Hungarian",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Hungarian", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="nl"; - translatemenu->append(new LLMenuItemCallGL("Dutch",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Dutch", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="pl"; - translatemenu->append(new LLMenuItemCallGL("Polish",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Polish", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="pt"; - translatemenu->append(new LLMenuItemCallGL("Portugese",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Portugese", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="ru"; - translatemenu->append(new LLMenuItemCallGL("Russian",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Russian", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="tr"; - translatemenu->append(new LLMenuItemCallGL("Turkish",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Turkish", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="uk"; - translatemenu->append(new LLMenuItemCallGL("Ukrainian",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Ukrainian", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="zh"; - translatemenu->append(new LLMenuItemCallGL("Chinese",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Chinese", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="ja"; - translatemenu->append(new LLMenuItemCallGL("Japanese",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Japanese", context_translate, context_enable_translate, t)); t=new SpellMenuBind;t->origin=this;t->word="ko"; - translatemenu->append(new LLMenuItemCallGL("Korean",translateText, NULL, t)); + translatemenu->append(new LLMenuItemCallGL("Korean", context_translate, context_enable_translate, t)); menu->appendMenu(translatemenu); menu->appendSeparator("Spelsep"); @@ -446,7 +439,6 @@ LLTextEditor::LLTextEditor( mPopupMenuHandle = menu->getHandle(); } - LLTextEditor::~LLTextEditor() { gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() @@ -464,18 +456,38 @@ LLTextEditor::~LLTextEditor() std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); LLView::deleteViewByHandle(mPopupMenuHandle); } + +BOOL LLTextEditor::context_enable_cut(void* data) +{ + LLTextEditor* line = (LLTextEditor*)data; + return (line && line->canCut()); +} + void LLTextEditor::context_cut(void* data) { LLTextEditor* line = (LLTextEditor*)data; if(line)line->cut(); } + +BOOL LLTextEditor::context_enable_copy(void* data) +{ + LLTextEditor* line = (LLTextEditor*)data; + return (line && line->canCopy()); +} + void LLTextEditor::context_copy(void* data) { LLTextEditor* line = (LLTextEditor*)data; if(line)line->copy(); } -void LLTextEditor::translateText(void * data) +BOOL LLTextEditor::context_enable_translate(void * data) +{ + SpellMenuBind* t = (SpellMenuBind*)data; + return (t && t->origin && t->origin->canTranslate()); +} + +void LLTextEditor::context_translate(void * data) { SpellMenuBind* t = (SpellMenuBind*)data; LLTextEditor* line = t->origin; @@ -523,14 +535,8 @@ void LLTextEditor::spell_show(void * data) if (tempBind && line) { - if (tempBind->word == "Show Misspellings") - { - glggHunSpell->setSpellCheckHighlight(TRUE); - } - else - { - glggHunSpell->setSpellCheckHighlight(FALSE); - } + BOOL show = (tempBind->word == "Show Misspellings"); + glggHunSpell->setSpellCheckHighlight(show); } } @@ -582,16 +588,37 @@ void LLTextEditor::spell_add(void* data) tempBind->origin->mPrevSpelledText.erase();//make it update } } + +BOOL LLTextEditor::context_enable_paste(void* data) +{ + LLTextEditor* line = (LLTextEditor*)data; + return(line && line->canPaste()); +} + void LLTextEditor::context_paste(void* data) { LLTextEditor* line = (LLTextEditor*)data; if(line)line->paste(); } + +BOOL LLTextEditor::context_enable_delete(void* data) +{ + LLTextEditor* line = (LLTextEditor*)data; + return (line && line->canDoDelete()); +} + void LLTextEditor::context_delete(void* data) { LLTextEditor* line = (LLTextEditor*)data; if(line)line->doDelete(); } + +BOOL LLTextEditor::context_enable_selectall(void* data) +{ + LLTextEditor* line = (LLTextEditor*)data; + return (line && line->canSelectAll()); +} + void LLTextEditor::context_selectall(void* data) { LLTextEditor* line = (LLTextEditor*)data; @@ -1506,16 +1533,11 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) } suggestionMenuItems.clear(); - bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordEnd); - - // allow_translate="true" in xui - bool can_translate = mAllowTranslate && !mReadOnly && (is_word_part || hasSelection()); - menu->setItemVisible("Translate To", can_translate); - menu->setItemVisible("Transep", can_translate); - // spell_check="true" in xui + menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable); if (!mReadOnly && mSpellCheckable) { + bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordEnd); if (is_word_part) { const LLWString &text = mWText; @@ -1526,7 +1548,6 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) //misspelled word here, and you have just right clicked on it! std::vector suggs = glggHunSpell->getSuggestionList(selectedWord); - //menu->setItemVisible("Transep",(suggs.size()>0)); for (int i = 0; i<(int)suggs.size(); i++) { SpellMenuBind * tempStruct = new SpellMenuBind; @@ -1557,7 +1578,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) SpellMenuBind * tempStruct = new SpellMenuBind; tempStruct->origin = this; - if (mShowMisspellings) + if (glggHunSpell->getSpellCheckHighlight()) { tempStruct->word = "Hide Misspellings"; } @@ -2301,6 +2322,14 @@ void LLTextEditor::translationReplace(const std::string &translation, const S32 needsReflow(); } +BOOL LLTextEditor::canTranslate() const +{ + // if allow_translate="true" in xui, and if other factors permit, we allow it + S32 pos = getCursorPosFromLocalCoord(mLastContextMenuX, mLastContextMenuY, TRUE); + bool is_word_part = (pos > -1) && isPartOfWord(mWText[pos]); + return (mAllowTranslate && !mReadOnly && (is_word_part || hasSelection())); +} + // paste from clipboard void LLTextEditor::paste() { @@ -3225,7 +3254,7 @@ void LLTextEditor::drawMisspelled() } } //draw - if (mShowMisspellings) + if (glggHunSpell->getSpellCheckHighlight()) { for (int i = 0; i<(int)misspellLocations.size() ;i++) { diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index 3269e17..f2a831b 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h @@ -137,6 +137,7 @@ public: virtual void spellReplace(SpellMenuBind* spellData); virtual void translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length); + virtual BOOL canTranslate() const; virtual void updatePrimary(); virtual void copyPrimary(); @@ -149,13 +150,19 @@ public: virtual BOOL canSelectAll() const; virtual void deselect(); virtual BOOL canDeselect() const; - static void context_cut(void* data); + static BOOL context_enable_cut(void* data); + static void context_cut(void* data); + static BOOL context_enable_copy(void* data); static void context_copy(void* data); + static BOOL context_enable_paste(void* data); static void context_paste(void* data); + static BOOL context_enable_delete(void* data); static void context_delete(void* data); + static BOOL context_enable_selectall(void* data); static void context_selectall(void* data); - static void translateText(void * data); + static BOOL context_enable_translate(void * data); + static void context_translate(void * data); static void spell_correct(void* data); static void spell_add(void* data); static void spell_show(void* data); @@ -529,7 +536,6 @@ private: S32 spellEnd; std::vector misspellLocations; // where all the mispelled words are BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field - BOOL mShowMisspellings; // show misspellings as highlighted (initialized in the ctor) BOOL mAllowTranslate; // set in xui as "allow_translate". S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes 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[] = { (char*)"CF",(char*)"Central African Republic", (char*)"CG",(char*)"Congo", (char*)"CH",(char*)"Switzerland", - (char*)"CI",(char*)"Côte D'ivoire (Ivory Coast)", + (char*)"CI",(char*)"Côte D'ivoire (Ivory Coast)", (char*)"CK",(char*)"Cook Iislands", (char*)"CL",(char*)"Chile", (char*)"CM",(char*)"Cameroon", @@ -212,7 +212,7 @@ static char * countryCodesraw[] = { (char*)"PW",(char*)"Palau", (char*)"PY",(char*)"Paraguay", (char*)"QA",(char*)"Qatar", - (char*)"RE",(char*)"Réunion", + (char*)"RE",(char*)"Réunion", (char*)"RO",(char*)"Romania", (char*)"RU",(char*)"Russian Federation", (char*)"RW",(char*)"Rwanda", @@ -333,7 +333,7 @@ static char * languageCodesraw[]={ (char*)"ga",(char*)"Irish", (char*)"gd",(char*)"Gaelic", (char*)"gl",(char*)"Galician", - (char*)"gn",(char*)"Guaraní", + (char*)"gn",(char*)"Guaraní", (char*)"gu",(char*)"Gujarati", (char*)"gv",(char*)"Manx", (char*)"ha",(char*)"Hausa", @@ -456,7 +456,7 @@ static char * languageCodesraw[]={ (char*)"uz",(char*)"Uzbek", (char*)"ve",(char*)"Venda", (char*)"vi",(char*)"Vietnamese", - (char*)"vo",(char*)"Volapük", + (char*)"vo",(char*)"Volapük", (char*)"wa",(char*)"Walloon", (char*)"wo",(char*)"Wolof", (char*)"xh",(char*)"Xhosa", @@ -470,10 +470,9 @@ static char * languageCodesraw[]={ #define LANGUAGE_CODES_RAW_SIZE 368 lggHunSpell_Wrapper::lggHunSpell_Wrapper() - : - mSpellCheckHighlight(false) { //languageCodes(begin(languageCodesraw), end(languageCodesraw)); + mSpellCheckHighlight = rebind_llcontrol("EmeraldSpellDisplay", &gSavedSettings, false); } lggHunSpell_Wrapper::~lggHunSpell_Wrapper() @@ -638,8 +637,6 @@ void lggHunSpell_Wrapper::processSettings() //expects everything to already be in saved settings //this will also reload and read the installed dicts setNewDictionary(gSavedSettings.getString("EmeraldSpellBase")); - mSpellCheckHighlight = gSavedSettings.getBOOL("EmeraldSpellDisplay"); - } void lggHunSpell_Wrapper::addDictionary(std::string additionalDictionary) @@ -966,5 +963,8 @@ void lggHunSpell_Wrapper::editCustomButton() void lggHunSpell_Wrapper::setSpellCheckHighlight(BOOL highlight) { - mSpellCheckHighlight = highlight; + if (mSpellCheckHighlight) + { + *mSpellCheckHighlight = highlight; + } } 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: std::string VEC2CSV(std::vector vec); void setSpellCheckHighlight(BOOL highlight); - BOOL getSpellCheckHighlight() { return mSpellCheckHighlight; } + BOOL getSpellCheckHighlight() { return mSpellCheckHighlight && *mSpellCheckHighlight; } private: void createCustomDic(); @@ -67,7 +67,7 @@ private: std::string currentBaseDic; //std::vector languageCodes; //std::vector countryCodes; - BOOL mSpellCheckHighlight; + BOOL* mSpellCheckHighlight; }; extern lggHunSpell_Wrapper* glggHunSpell; // the singleton hunspell wrapper -- cgit v1.1