From 1cc154166fe504e17735669b7b9e366f93e34d64 Mon Sep 17 00:00:00 2001 From: Tank_Master Date: Tue, 20 Dec 2011 22:17:20 -0800 Subject: STORM-1738 - Add autocorrect functionality Ported with owner permission from Firestorm, inital work done by LordGregGreg Back --- indra/llui/lllineeditor.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 06dfc90d83..cee84cc53f 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -51,6 +51,8 @@ #include "lluictrlfactory.h" #include "llclipboard.h" #include "llmenugl.h" +#include "../newview/llautocorrect.h" +#include "../newview/llviewercontrol.h" // // Imported globals @@ -194,7 +196,60 @@ LLLineEditor::~LLLineEditor() // calls onCommit() while LLLineEditor still valid gFocusMgr.releaseFocusIfNeeded( this ); } +void LLLineEditor::autoCorrectText() +{ + static LLCachedControl doAnything(gSavedSettings, "EnableAutoCorrect"); + if( (!mReadOnly) && (doAnything))// && (isDirty())) + { + S32 wordStart = 0; + S32 wordEnd = mCursorPos-1; + //llinfos <<"Checking Word, Cursor is at "< 0) && (' '!=text[wordEnd-1])) + { + wordEnd--; + } + + wordStart=wordEnd; + + while ((wordEnd < (S32)text.length()) && (' '!=text[wordEnd] ) ) + { + wordEnd++; + } + + std::string strLastWord = std::string(text.begin(), text.end()); + std::string lastTypedWord = strLastWord.substr( wordStart, wordEnd-wordStart); + std::string correctedWord( AutoCorrect::getInstance()->replaceWord(lastTypedWord)); + if(correctedWord!=lastTypedWord) + { + LLWString strNew = utf8str_to_wstring( correctedWord ); + LLWString strOld = utf8str_to_wstring( lastTypedWord ); + int nDiff = strNew.size() - strOld.size(); + + //int wordStart = regText.find(lastTypedWord); + text.replace(wordStart,lastTypedWord.length(),strNew); + mText = wstring_to_utf8str(text); + mCursorPos+=nDiff; + } + } + } +} void LLLineEditor::onFocusReceived() { @@ -866,6 +921,8 @@ void LLLineEditor::addChar(const llwchar uni_char) LLUI::reportBadKeystroke(); } + autoCorrectText(); + getWindow()->hideCursorUntilMouseMove(); } -- cgit v1.2.3 From f0d1afc2266e13b4f36f750ba5e721e427caf7b8 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Fri, 20 Jan 2012 18:07:35 +0100 Subject: STORM-276 Added spellcheck functionality to the LLLineEditor control --- indra/llui/lllineeditor.cpp | 217 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 214 insertions(+), 3 deletions(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 06dfc90d83..5479c080bd 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -45,6 +45,7 @@ #include "llkeyboard.h" #include "llrect.h" #include "llresmgr.h" +#include "llspellcheck.h" #include "llstring.h" #include "llwindow.h" #include "llui.h" @@ -65,6 +66,7 @@ const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing const F32 AUTO_SCROLL_TIME = 0.05f; const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval? +const F32 SPELLCHECK_DELAY = 0.5f; // delay between the last keypress and showing spell checking feedback for the word the cursor is on const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET @@ -88,6 +90,7 @@ LLLineEditor::Params::Params() background_image_focused("background_image_focused"), select_on_focus("select_on_focus", false), revert_on_esc("revert_on_esc", true), + spellcheck("spellcheck", false), commit_on_focus_lost("commit_on_focus_lost", true), ignore_tab("ignore_tab", true), is_password("is_password", false), @@ -134,6 +137,9 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mIgnoreArrowKeys( FALSE ), mIgnoreTab( p.ignore_tab ), mDrawAsterixes( p.is_password ), + mSpellCheck( p.spellcheck ), + mSpellCheckStart(-1), + mSpellCheckEnd(-1), mSelectAllonFocusReceived( p.select_on_focus ), mSelectAllonCommit( TRUE ), mPassDelete(FALSE), @@ -177,6 +183,12 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) updateTextPadding(); setCursor(mText.length()); + if (mSpellCheck) + { + LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLLineEditor::onSpellCheckSettingsChange, this)); + } + mSpellCheckTimer.reset(); + setPrevalidateInput(p.prevalidate_input_callback()); setPrevalidate(p.prevalidate_callback()); @@ -519,6 +531,94 @@ void LLLineEditor::selectAll() updatePrimary(); } +bool LLLineEditor::getSpellCheck() const +{ + return (LLSpellChecker::getUseSpellCheck()) && (!mReadOnly) && (mSpellCheck); +} + +const std::string& LLLineEditor::getSuggestion(U32 index) const +{ + return (index < mSuggestionList.size()) ? mSuggestionList[index] : LLStringUtil::null; +} + +U32 LLLineEditor::getSuggestionCount() const +{ + return mSuggestionList.size(); +} + +void LLLineEditor::replaceWithSuggestion(U32 index) +{ + for (std::list >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it) + { + if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) ) + { + deselect(); + + // Delete the misspelled word + mText.erase(it->first, it->second - it->first); + + // Insert the suggestion in its place + LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]); + mText.insert(it->first, suggestion); + setCursor(it->first + (S32)suggestion.length()); + + break; + } + } + mSpellCheckStart = mSpellCheckEnd = -1; +} + +void LLLineEditor::addToDictionary() +{ + if (canAddToDictionary()) + { + LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos)); + } +} + +bool LLLineEditor::canAddToDictionary() const +{ + return (getSpellCheck()) && (isMisspelledWord(mCursorPos)); +} + +void LLLineEditor::addToIgnore() +{ + if (canAddToIgnore()) + { + LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos)); + } +} + +bool LLLineEditor::canAddToIgnore() const +{ + return (getSpellCheck()) && (isMisspelledWord(mCursorPos)); +} + +std::string LLLineEditor::getMisspelledWord(U32 pos) const +{ + for (std::list >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it) + { + if ( (it->first <= pos) && (it->second >= pos) ) + return wstring_to_utf8str(mText.getWString().substr(it->first, it->second - it->first)); + } + return LLStringUtil::null; +} + +bool LLLineEditor::isMisspelledWord(U32 pos) const +{ + for (std::list >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it) + { + if ( (it->first <= pos) && (it->second >= pos) ) + return true; + } + return false; +} + +void LLLineEditor::onSpellCheckSettingsChange() +{ + // Recheck the spelling on every change + mSpellCheckStart = mSpellCheckEnd = -1; +} BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask) { @@ -1453,6 +1553,10 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask ) { mKeystrokeCallback(this); } + if ( (!selection_modified) && (KEY_BACKSPACE == key) ) + { + mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); + } } } } @@ -1510,6 +1614,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char) // We'll have to do something about this if something ever changes! - Doug mKeystrokeCallback( this ); } + mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); } } return handled; @@ -1560,6 +1665,7 @@ void LLLineEditor::doDelete() { mKeystrokeCallback( this ); } + mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); } } } @@ -1756,7 +1862,7 @@ void LLLineEditor::draw() if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) ) { // unselected, right side - mGLFont->render( + rendered_text += mGLFont->render( mText, mScrollHPos + rendered_text, rendered_pixels_right, text_bottom, text_color, @@ -1770,7 +1876,7 @@ void LLLineEditor::draw() } else { - mGLFont->render( + rendered_text = mGLFont->render( mText, mScrollHPos, rendered_pixels_right, text_bottom, text_color, @@ -1785,6 +1891,80 @@ void LLLineEditor::draw() mBorder->setVisible(FALSE); // no more programmatic art. #endif + if ( (getSpellCheck()) && (mText.length() > 2) ) + { + // Calculate start and end indices for the first and last visible word + U32 start = prevWordPos(mScrollHPos), end = nextWordPos(mScrollHPos + rendered_text); + + if ( (mSpellCheckStart != start) || (mSpellCheckEnd = end) ) + { + const LLWString& text = mText.getWString().substr(start, end); + + // Find the start of the first word + U32 word_start = 0, word_end = 0; + while ( (word_start < text.length()) && (!LLStringOps::isAlpha(text[word_start])) ) + word_start++; + + // Iterate over all words in the text block and check them one by one + mMisspellRanges.clear(); + while (word_start < text.length()) + { + // Find the end of the current word (special case handling for "'" when it's used as a contraction) + word_end = word_start + 1; + while ( (word_end < text.length()) && + ((LLWStringUtil::isPartOfWord(text[word_end])) || + ((L'\'' == text[word_end]) && (word_end + 1 < text.length()) && + (LLStringOps::isAlnum(text[word_end - 1])) && (LLStringOps::isAlnum(text[word_end + 1])))) ) + { + word_end++; + } + if (word_end >= text.length()) + break; + + // Don't process words shorter than 3 characters + std::string word = wstring_to_utf8str(text.substr(word_start, word_end - word_start)); + if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) ) + mMisspellRanges.push_back(std::pair(start + word_start, start + word_end)); + + // Find the start of the next word + word_start = word_end + 1; + while ( (word_start < text.length()) && (!LLWStringUtil::isPartOfWord(text[word_start])) ) + word_start++; + } + + mSpellCheckStart = start; + mSpellCheckEnd = end; + } + + // Draw squiggly lines under any (visible) misspelled words + for (std::list >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it) + { + // Skip over words that aren't (partially) visible + if ( ((it->first < start) && (it->second < start)) || (it->first > end) ) + continue; + + // Skip the current word if the user is still busy editing it + if ( (!mSpellCheckTimer.hasExpired()) && (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) ) + continue; + + S32 pxWidth = getRect().getWidth(); + S32 pxStart = findPixelNearestPos(it->first - getCursor()); + if (pxStart > pxWidth) + continue; + S32 pxEnd = findPixelNearestPos(it->second - getCursor()); + if (pxEnd > pxWidth) + pxEnd = pxWidth; + + gGL.color4ub(255, 0, 0, 200); + while (pxStart < pxEnd) + { + gl_line_2d(pxStart, text_bottom - 2, pxStart + 3, text_bottom + 1); + gl_line_2d(pxStart + 3, text_bottom + 1, pxStart + 6, text_bottom - 2); + pxStart += 6; + } + } + } + // If we're editing... if( hasFocus()) { @@ -2242,6 +2422,7 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string, { mKeystrokeCallback( this ); } + mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); } BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const @@ -2393,7 +2574,37 @@ void LLLineEditor::showContextMenu(S32 x, S32 y) S32 screen_x, screen_y; localPointToScreen(x, y, &screen_x, &screen_y); - menu->show(screen_x, screen_y); + + if (hasSelection()) + { + if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) ) + deselect(); + else + setCursor(llmax(mSelectionStart, mSelectionEnd)); + } + else + { + setCursorAtLocalPos(x); + } + + bool use_spellcheck = getSpellCheck(), is_misspelled = false; + if (use_spellcheck) + { + mSuggestionList.clear(); + + // If the cursor is on a misspelled word, retrieve suggestions for it + std::string misspelled_word = getMisspelledWord(mCursorPos); + if ((is_misspelled = !misspelled_word.empty()) == true) + { + LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList); + } + } + + menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty())); + menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled)); + menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled)); + menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled)); + menu->show(screen_x, screen_y, this); } } -- cgit v1.2.3 From 59dfcba33de76bfc998b9aa2121c53dff75024f7 Mon Sep 17 00:00:00 2001 From: Jonathan Yap Date: Wed, 1 Feb 2012 10:28:45 -0500 Subject: STORM-1738 Slight adjustment to callback --- indra/llui/lllineeditor.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index ba50728e89..de951d3b56 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -151,7 +151,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mHighlightColor(p.highlight_color()), mPreeditBgColor(p.preedit_bg_color()), mGLFont(p.font), - mContextMenuHandle() + mContextMenuHandle(), + mAutocorrectCallback() { llassert( mMaxLengthBytes > 0 ); @@ -866,10 +867,10 @@ void LLLineEditor::addChar(const llwchar uni_char) } // *TODO implement callback routine - if (!mReadOnly /*&& autocorrectCallbackRoutine != NULL */) + if (!mReadOnly && mAutocorrectCallback != NULL) { // call callback - // autotocorrectCallbackRoutine(mText&, mCursorPos&); + // mAutotocorrectCallback(mText&, mCursorPos&); } getWindow()->hideCursorUntilMouseMove(); -- cgit v1.2.3 From 41e11a508379d8f6d2b95f835d2df9f4e2bbea01 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Fri, 3 Feb 2012 15:34:52 +0100 Subject: STORM-276 FIXED Selecting a character in a line editor and replacing it doesn't trigger a spell check --- indra/llui/lllineeditor.cpp | 53 ++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 5479c080bd..e67753292e 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -66,7 +66,7 @@ const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing const F32 AUTO_SCROLL_TIME = 0.05f; const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval? -const F32 SPELLCHECK_DELAY = 0.5f; // delay between the last keypress and showing spell checking feedback for the word the cursor is on +const F32 SPELLCHECK_DELAY = 0.5f; // delay between the last keypress and spell checking the word the cursor is on const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET @@ -1158,9 +1158,8 @@ void LLLineEditor::cut() LLUI::reportBadKeystroke(); } else - if( mKeystrokeCallback ) { - mKeystrokeCallback( this ); + onKeystroke(); } } } @@ -1294,9 +1293,8 @@ void LLLineEditor::pasteHelper(bool is_primary) LLUI::reportBadKeystroke(); } else - if( mKeystrokeCallback ) { - mKeystrokeCallback( this ); + onKeystroke(); } } } @@ -1549,10 +1547,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask ) // Notify owner if requested if (!need_to_rollback && handled) { - if (mKeystrokeCallback) - { - mKeystrokeCallback(this); - } + onKeystroke(); if ( (!selection_modified) && (KEY_BACKSPACE == key) ) { mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); @@ -1608,12 +1603,10 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char) // Notify owner if requested if( !need_to_rollback && handled ) { - if( mKeystrokeCallback ) - { - // HACK! The only usage of this callback doesn't do anything with the character. - // We'll have to do something about this if something ever changes! - Doug - mKeystrokeCallback( this ); - } + // HACK! The only usage of this callback doesn't do anything with the character. + // We'll have to do something about this if something ever changes! - Doug + onKeystroke(); + mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); } } @@ -1643,9 +1636,7 @@ void LLLineEditor::doDelete() if (!prevalidateInput(text_to_delete)) { - if( mKeystrokeCallback ) - mKeystrokeCallback( this ); - + onKeystroke(); return; } setCursor(getCursor() + 1); @@ -1661,10 +1652,8 @@ void LLLineEditor::doDelete() } else { - if( mKeystrokeCallback ) - { - mKeystrokeCallback( this ); - } + onKeystroke(); + mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); } } @@ -2296,6 +2285,15 @@ void LLLineEditor::setSelectAllonFocusReceived(BOOL b) mSelectAllonFocusReceived = b; } +void LLLineEditor::onKeystroke() +{ + if (mKeystrokeCallback) + { + mKeystrokeCallback(this); + } + + mSpellCheckStart = mSpellCheckEnd = -1; +} void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data) { @@ -2418,10 +2416,8 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string, // Update of the preedit should be caused by some key strokes. mKeystrokeTimer.reset(); - if( mKeystrokeCallback ) - { - mKeystrokeCallback( this ); - } + onKeystroke(); + mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); } @@ -2575,6 +2571,7 @@ void LLLineEditor::showContextMenu(S32 x, S32 y) S32 screen_x, screen_y; localPointToScreen(x, y, &screen_x, &screen_y); + setCursorAtLocalPos(x); if (hasSelection()) { if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) ) @@ -2582,10 +2579,6 @@ void LLLineEditor::showContextMenu(S32 x, S32 y) else setCursor(llmax(mSelectionStart, mSelectionEnd)); } - else - { - setCursorAtLocalPos(x); - } bool use_spellcheck = getSpellCheck(), is_misspelled = false; if (use_spellcheck) -- cgit v1.2.3 From 49e0c38ee85214eb7d0e7e995d1a380ee2f60720 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Fri, 3 Feb 2012 19:45:00 +0100 Subject: STORM-276 Added preferences panel --- indra/llui/lllineeditor.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index e67753292e..42cfc4cae9 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -617,6 +617,7 @@ bool LLLineEditor::isMisspelledWord(U32 pos) const void LLLineEditor::onSpellCheckSettingsChange() { // Recheck the spelling on every change + mMisspellRanges.clear(); mSpellCheckStart = mSpellCheckEnd = -1; } -- cgit v1.2.3 From 59bfc3f608bed806e03898b833a0fda9f95d42b9 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 25 Mar 2012 19:50:46 +0200 Subject: Minor fix for GCC --- indra/llui/lllineeditor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 42cfc4cae9..0dc381231d 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1948,8 +1948,8 @@ void LLLineEditor::draw() gGL.color4ub(255, 0, 0, 200); while (pxStart < pxEnd) { - gl_line_2d(pxStart, text_bottom - 2, pxStart + 3, text_bottom + 1); - gl_line_2d(pxStart + 3, text_bottom + 1, pxStart + 6, text_bottom - 2); + gl_line_2d(pxStart, (S32)text_bottom - 2, pxStart + 3, (S32)text_bottom + 1); + gl_line_2d(pxStart + 3, (S32)text_bottom + 1, pxStart + 6, (S32)text_bottom - 2); pxStart += 6; } } -- cgit v1.2.3 From 22f26725b902cb2e942048d059710169666e4a45 Mon Sep 17 00:00:00 2001 From: Jonathan Yap Date: Fri, 10 Feb 2012 17:40:58 -0500 Subject: STORM-1738 Autocorrect working for nearby chat and IM input boxes warn-on-failure:open-license --- indra/llui/lllineeditor.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index de951d3b56..4d0b972bf1 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -866,11 +866,10 @@ void LLLineEditor::addChar(const llwchar uni_char) LLUI::reportBadKeystroke(); } -// *TODO implement callback routine if (!mReadOnly && mAutocorrectCallback != NULL) { // call callback - // mAutotocorrectCallback(mText&, mCursorPos&); + mAutocorrectCallback(mText, mCursorPos); } getWindow()->hideCursorUntilMouseMove(); -- cgit v1.2.3 From 9bdb1d82f867147af44def8c1cca3dfb8259b99c Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 11 May 2012 12:22:43 -0400 Subject: rename feature from "autocorrect" to "autoreplace", change names accordingly --- indra/llui/lllineeditor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 1f7843b79d..0f328aa065 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -152,7 +152,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mPreeditBgColor(p.preedit_bg_color()), mGLFont(p.font), mContextMenuHandle(), - mAutocorrectCallback() + mAutoreplaceCallback() { llassert( mMaxLengthBytes > 0 ); @@ -866,10 +866,10 @@ void LLLineEditor::addChar(const llwchar uni_char) LLUI::reportBadKeystroke(); } - if (!mReadOnly && mAutocorrectCallback != NULL) + if (!mReadOnly && mAutoreplaceCallback != NULL) { // call callback - mAutocorrectCallback(mText, mCursorPos); + mAutoreplaceCallback(mText, mCursorPos); } getWindow()->hideCursorUntilMouseMove(); -- cgit v1.2.3 From 34e7226ac88e14d4cfed6bc0d63da215afe0ac88 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Tue, 15 May 2012 13:13:44 +0200 Subject: STORM-276 FIXED Squiggles overflow line editor height when font size is set to large - Also reduced squiggle width from 6 to 4 and prevented running past the end of a word --- indra/llui/lllineeditor.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index f119b0d9bc..d87b9d930c 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1727,6 +1727,10 @@ void LLLineEditor::draw() background.stretch( -mBorderThickness ); S32 lineeditor_v_pad = (background.getHeight() - mGLFont->getLineHeight()) / 2; + if (mSpellCheck) + { + lineeditor_v_pad += 1; + } drawBackground(); @@ -1945,12 +1949,15 @@ void LLLineEditor::draw() if (pxEnd > pxWidth) pxEnd = pxWidth; + S32 pxBottom = (S32)(text_bottom + mGLFont->getDescenderHeight()); + gGL.color4ub(255, 0, 0, 200); - while (pxStart < pxEnd) + while (pxStart + 1 < pxEnd) { - gl_line_2d(pxStart, (S32)text_bottom - 2, pxStart + 3, (S32)text_bottom + 1); - gl_line_2d(pxStart + 3, (S32)text_bottom + 1, pxStart + 6, (S32)text_bottom - 2); - pxStart += 6; + gl_line_2d(pxStart, pxBottom, pxStart + 2, pxBottom - 2); + if (pxStart + 3 < pxEnd) + gl_line_2d(pxStart + 2, pxBottom - 3, pxStart + 4, pxBottom - 1); + pxStart += 4; } } } -- cgit v1.2.3 From 8199cc997aeaccc72b5bd5389ded8afc7b9c379c Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Tue, 15 May 2012 14:09:13 +0200 Subject: STORM-276 FIXED Right-to-left line editor selection becomes invisible if the cursor moves --- indra/llui/lllineeditor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index d87b9d930c..83527ae5ad 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1805,14 +1805,14 @@ void LLLineEditor::draw() { S32 select_left; S32 select_right; - if( mSelectionStart < getCursor() ) + if (mSelectionStart < mSelectionEnd) { select_left = mSelectionStart; - select_right = getCursor(); + select_right = mSelectionEnd; } else { - select_left = getCursor(); + select_left = mSelectionEnd; select_right = mSelectionStart; } -- cgit v1.2.3 From d7303541ccd4ea1420de4cd11ff824aeb171fae7 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Thu, 31 May 2012 17:37:19 +0200 Subject: STORM-276 FIXED Line editor misspells are checked every frame --- indra/llui/lllineeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 352854c629..1e0b194e44 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1883,7 +1883,7 @@ void LLLineEditor::draw() // Calculate start and end indices for the first and last visible word U32 start = prevWordPos(mScrollHPos), end = nextWordPos(mScrollHPos + rendered_text); - if ( (mSpellCheckStart != start) || (mSpellCheckEnd = end) ) + if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) ) { const LLWString& text = mText.getWString().substr(start, end); -- cgit v1.2.3 From e2e33c0ed5f2acbbfe35c46b1298ed56eb9d1003 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Thu, 31 May 2012 20:47:14 +0200 Subject: STORM-276 FIXED Last word in a line editor isn't spell checked --- indra/llui/lllineeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 1e0b194e44..ae1f7f2419 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1905,7 +1905,7 @@ void LLLineEditor::draw() { word_end++; } - if (word_end >= text.length()) + if (word_end > text.length()) break; // Don't process words shorter than 3 characters -- cgit v1.2.3 From 80b1a2c0a8f7b4444dc1588ba5f71bbb69b40acd Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Mon, 11 Jun 2012 13:39:45 +0200 Subject: STORM-276 Insert braces around if/for/while loops --- indra/llui/lllineeditor.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'indra/llui/lllineeditor.cpp') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index ae1f7f2419..2a92337388 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -599,7 +599,9 @@ std::string LLLineEditor::getMisspelledWord(U32 pos) const for (std::list >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it) { if ( (it->first <= pos) && (it->second >= pos) ) + { return wstring_to_utf8str(mText.getWString().substr(it->first, it->second - it->first)); + } } return LLStringUtil::null; } @@ -609,7 +611,9 @@ bool LLLineEditor::isMisspelledWord(U32 pos) const for (std::list >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it) { if ( (it->first <= pos) && (it->second >= pos) ) + { return true; + } } return false; } @@ -1890,7 +1894,9 @@ void LLLineEditor::draw() // Find the start of the first word U32 word_start = 0, word_end = 0; while ( (word_start < text.length()) && (!LLStringOps::isAlpha(text[word_start])) ) + { word_start++; + } // Iterate over all words in the text block and check them one by one mMisspellRanges.clear(); @@ -1906,17 +1912,23 @@ void LLLineEditor::draw() word_end++; } if (word_end > text.length()) + { break; + } // Don't process words shorter than 3 characters std::string word = wstring_to_utf8str(text.substr(word_start, word_end - word_start)); if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) ) + { mMisspellRanges.push_back(std::pair(start + word_start, start + word_end)); + } // Find the start of the next word word_start = word_end + 1; while ( (word_start < text.length()) && (!LLWStringUtil::isPartOfWord(text[word_start])) ) + { word_start++; + } } mSpellCheckStart = start; @@ -1928,19 +1940,27 @@ void LLLineEditor::draw() { // Skip over words that aren't (partially) visible if ( ((it->first < start) && (it->second < start)) || (it->first > end) ) + { continue; + } // Skip the current word if the user is still busy editing it if ( (!mSpellCheckTimer.hasExpired()) && (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) ) + { continue; + } S32 pxWidth = getRect().getWidth(); S32 pxStart = findPixelNearestPos(it->first - getCursor()); if (pxStart > pxWidth) + { continue; + } S32 pxEnd = findPixelNearestPos(it->second - getCursor()); if (pxEnd > pxWidth) + { pxEnd = pxWidth; + } S32 pxBottom = (S32)(text_bottom + mGLFont->getDescenderHeight()); @@ -1949,7 +1969,9 @@ void LLLineEditor::draw() { gl_line_2d(pxStart, pxBottom, pxStart + 2, pxBottom - 2); if (pxStart + 3 < pxEnd) + { gl_line_2d(pxStart + 2, pxBottom - 3, pxStart + 4, pxBottom - 1); + } pxStart += 4; } } @@ -2576,9 +2598,13 @@ void LLLineEditor::showContextMenu(S32 x, S32 y) if (hasSelection()) { if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) ) + { deselect(); + } else + { setCursor(llmax(mSelectionStart, mSelectionEnd)); + } } bool use_spellcheck = getSpellCheck(), is_misspelled = false; -- cgit v1.2.3