CHUI-291 FIX New auto-replace feature does not work with chui text input boxes in conversation floater
Modified LLAutoReplace to pass back a string for replacement instead of modifying the input stringmaster
parent
d67804543d
commit
163f3de73d
|
|
@ -1101,16 +1101,17 @@ void LLTextEditor::addChar(llwchar wc)
|
|||
|
||||
if (!mReadOnly && mAutoreplaceCallback != NULL)
|
||||
{
|
||||
// autoreplace on a copy of the text (so we can go through proper channels to set it later)
|
||||
LLWString new_text(getWText());
|
||||
S32 new_cursor_pos(mCursorPos);
|
||||
mAutoreplaceCallback(new_text, new_cursor_pos);
|
||||
|
||||
if (new_text != getWText())
|
||||
// autoreplace the text, if necessary
|
||||
S32 replacement_start;
|
||||
S32 replacement_length;
|
||||
LLWString replacement_string;
|
||||
S32 new_cursor_pos = mCursorPos;
|
||||
mAutoreplaceCallback(replacement_start, replacement_length, replacement_string, new_cursor_pos, getWText());
|
||||
|
||||
if (replacement_length > 0 || !replacement_string.empty())
|
||||
{
|
||||
// setText() might be simpler here but it wipes the undo stack (bad)
|
||||
remove(0, getWText().length(), true);
|
||||
insert(0, new_text, false, LLTextSegmentPtr());
|
||||
remove(replacement_start, replacement_length, true);
|
||||
insert(replacement_start, replacement_string, false, LLTextSegmentPtr());
|
||||
setCursorPos(new_cursor_pos);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public:
|
|||
BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
|
||||
|
||||
// Autoreplace (formerly part of LLLineEditor)
|
||||
typedef boost::function<void(LLWString&, S32&)> autoreplace_callback_t;
|
||||
typedef boost::function<void(S32&, S32&, LLWString&, S32&, const LLWString&)> autoreplace_callback_t;
|
||||
autoreplace_callback_t mAutoreplaceCallback;
|
||||
void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
|
||||
|
||||
|
|
|
|||
|
|
@ -32,53 +32,58 @@
|
|||
|
||||
const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml";
|
||||
|
||||
void LLAutoReplace::autoreplaceCallback(LLWString& inputText, S32& cursorPos)
|
||||
void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text)
|
||||
{
|
||||
// make sure these returned values are cleared in case there is no replacement
|
||||
replacement_start = 0;
|
||||
replacement_length = 0;
|
||||
replacement_string.clear();
|
||||
|
||||
static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
|
||||
if(perform_autoreplace)
|
||||
if (perform_autoreplace)
|
||||
{
|
||||
S32 wordEnd = cursorPos-1;
|
||||
S32 word_end = cursor_pos - 1;
|
||||
|
||||
bool atSpace = (inputText[wordEnd] == ' ');
|
||||
bool haveWord = (LLWStringUtil::isPartOfWord(inputText[wordEnd]));
|
||||
bool at_space = (input_text[word_end] == ' ');
|
||||
bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end]));
|
||||
|
||||
if (atSpace || haveWord)
|
||||
if (at_space || have_word)
|
||||
{
|
||||
if (atSpace && wordEnd > 0)
|
||||
if (at_space && word_end > 0)
|
||||
{
|
||||
// find out if this space immediately follows a word
|
||||
wordEnd--;
|
||||
haveWord = (LLWStringUtil::isPartOfWord(inputText[wordEnd]));
|
||||
word_end--;
|
||||
have_word = (LLWStringUtil::isPartOfWord(input_text[word_end]));
|
||||
}
|
||||
if (haveWord)
|
||||
if (have_word)
|
||||
{
|
||||
// wordEnd points to the end of a word, now find the start of the word
|
||||
// word_end points to the end of a word, now find the start of the word
|
||||
std::string word;
|
||||
S32 wordStart = wordEnd;
|
||||
for ( S32 backOne = wordStart - 1;
|
||||
backOne >= 0 && LLWStringUtil::isPartOfWord(inputText[backOne]);
|
||||
backOne--
|
||||
)
|
||||
S32 word_start = word_end;
|
||||
for (S32 back_one = word_start - 1;
|
||||
back_one >= 0 && LLWStringUtil::isPartOfWord(input_text[back_one]);
|
||||
back_one--
|
||||
)
|
||||
{
|
||||
wordStart--; // walk wordStart back to the beginning of the word
|
||||
word_start--; // walk word_start back to the beginning of the word
|
||||
}
|
||||
LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL;
|
||||
std::string strText = std::string(inputText.begin(), inputText.end());
|
||||
std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1);
|
||||
std::string replacementWord( mSettings.replaceWord( lastWord ) );
|
||||
LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL;
|
||||
std::string str_text = std::string(input_text.begin(), input_text.end());
|
||||
std::string last_word = str_text.substr(word_start, word_end - word_start + 1);
|
||||
std::string replacement_word(mSettings.replaceWord(last_word));
|
||||
|
||||
if ( replacementWord != lastWord )
|
||||
if (replacement_word != last_word)
|
||||
{
|
||||
// The last word is one for which we have a replacement
|
||||
if (atSpace)
|
||||
if (at_space)
|
||||
{
|
||||
// replace the last word in the input
|
||||
LLWString strNew = utf8str_to_wstring(replacementWord);
|
||||
LLWString strOld = utf8str_to_wstring(lastWord);
|
||||
int size_change = strNew.size() - strOld.size();
|
||||
|
||||
inputText.replace(wordStart,lastWord.length(),strNew);
|
||||
cursorPos+=size_change;
|
||||
// return the replacement string
|
||||
replacement_start = word_start;
|
||||
replacement_length = last_word.length();
|
||||
replacement_string = utf8str_to_wstring(replacement_word);
|
||||
LLWString old_string = utf8str_to_wstring(last_word);
|
||||
S32 size_change = replacement_string.size() - old_string.size();
|
||||
cursor_pos += size_change;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,7 +183,8 @@ class LLAutoReplaceSettings
|
|||
* When the end of a word is detected (defined as any punctuation character,
|
||||
* or any whitespace except newline or return), the preceding word is used
|
||||
* as a lookup key in an ordered list of maps. If a match is found in any
|
||||
* map, the keyword is replaced by the associated value from the map.
|
||||
* map, the replacement start index and length are returned along with the
|
||||
* new replacement string.
|
||||
*
|
||||
* See the autoreplaceCallback method for how to add autoreplace functionality
|
||||
* to a text entry tool.
|
||||
|
|
@ -192,7 +193,7 @@ class LLAutoReplace : public LLSingleton<LLAutoReplace>
|
|||
{
|
||||
public:
|
||||
/// Callback that provides the hook for use in text entry methods
|
||||
void autoreplaceCallback(LLWString& inputText, S32& cursorPos);
|
||||
void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text);
|
||||
|
||||
/// Get a copy of the current settings
|
||||
LLAutoReplaceSettings getSettings();
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ BOOL LLFloaterIMNearbyChat::postBuild()
|
|||
setIsSingleInstance(TRUE);
|
||||
BOOL result = LLFloaterIMSessionTab::postBuild();
|
||||
|
||||
mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
|
||||
mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
|
||||
mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
|
||||
mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
|
||||
mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ BOOL LLFloaterIMSession::postBuild()
|
|||
BOOL result = LLFloaterIMSessionTab::postBuild();
|
||||
|
||||
mInputEditor->setMaxTextLength(1023);
|
||||
mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
|
||||
mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
|
||||
mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
|
||||
mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
|
||||
mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
|
||||
|
|
|
|||
Loading…
Reference in New Issue