void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) { static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace"); if(perform_autoreplace) { S32 wordEnd = cursorPos-1; LLWString text = inputText.getWString(); bool atSpace = (text[wordEnd] == ' '); bool haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd])); if (atSpace || haveWord) { if (atSpace && wordEnd > 0) { // find out if this space immediately follows a word wordEnd--; haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd])); } if (haveWord) { // wordEnd 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(text[backOne]); backOne-- ) { wordStart--; // walk wordStart back to the beginning of the word } LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL; std::string strText = std::string(text.begin(), text.end()); std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1); std::string replacementWord( mSettings.replaceWord( lastWord ) ); if ( replacementWord != lastWord ) { // The last word is one for which we have a replacement if (atSpace) { // 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(); text.replace(wordStart,lastWord.length(),strNew); inputText = wstring_to_utf8str(text); cursorPos+=size_change; } } } } } }
bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) { // boost::regex_search() only works on char or wchar_t // types, but wchar_t is only 2-bytes on Win32 (not 4). // So we use UTF-8 to make this work the same everywhere. std::string utf8_text = wstring_to_utf8str(text); if (findUrl(utf8_text, match, cb)) { // we cannot blindly return the start/end offsets from // the UTF-8 string because it is a variable-length // character encoding, so we need to update the start // and end values to be correct for the wide string. LLWString wurl = utf8str_to_wstring(match.getUrl()); S32 start = text.find(wurl); if (start == std::string::npos) { return false; } S32 end = start + wurl.size() - 1; match.setValues(start, end, match.getUrl(), match.getLabel(), match.getTooltip(), match.getIcon(), match.getStyle(), match.getMenuName(), match.getLocation(), match.getID(), match.underlineOnHoverOnly()); return true; } return false; }
bool LLUrlRegistry::isUrl(const LLWString &text) { LLUrlMatch match; if (findUrl(text, match)) { return (match.getStart() == 0 && match.getEnd() >= text.size()-1); } return false; }
void LLViewerTextEditor::setEmbeddedText(const std::string& instr) { LLWString wtext = utf8str_to_wstring(instr); for (S32 i=0; i<(S32)wtext.size(); i++) { llwchar wch = wtext[i]; if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) { S32 index = wch - FIRST_EMBEDDED_CHAR; wtext[i] = mEmbeddedItemList->getEmbeddedCharFromIndex(index); } } setWText(wtext); }
void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width) { if (max_width < 0.0) { max_width = (F32)getRect().getWidth(); } LLWString wtext = utf8str_to_wstring(in_text); LLWString final_wtext; LLWString::size_type cur = 0;; LLWString::size_type len = wtext.size(); while (cur < len) { LLWString::size_type end = wtext.find('\n', cur); if (end == LLWString::npos) { end = len; } LLWString::size_type runLen = end - cur; if (runLen > 0) { LLWString run(wtext, cur, runLen); LLWString::size_type useLen = mFontGL->maxDrawableChars(run.c_str(), max_width, runLen, TRUE); final_wtext.append(wtext, cur, useLen); cur += useLen; } if (cur < len) { if (wtext[cur] == '\n') { cur += 1; } final_wtext += '\n'; } } std::string final_text = wstring_to_utf8str(final_wtext); setText(final_text); }
void LLConsole::addQueuedLines() { for (line_queue_t::iterator iter = mLineQueue.begin(); iter != mLineQueue.end(); ++iter) { LineInfo& line_info = *iter; LLWString wline = line_info.wline; //F32 size = line_info.size; LLColor4 color = line_info.color; if (!wline.empty() && mFont != NULL) { // Wrap lines that are longer than the view is wide. S32 offset = 0; while( offset < (S32)wline.length() ) { S32 skip_chars; // skip '\n' // Figure out if a word-wrapped line fits here. LLWString::size_type line_end = wline.find_first_of(llwchar('\n'), offset); if (line_end != LLWString::npos) { skip_chars = 1; // skip '\n' } else { line_end = wline.size(); skip_chars = 0; } U32 drawable = mFont->maxDrawableChars(wline.c_str()+offset, (F32)mRect.getWidth(), line_end-offset, TRUE); if (drawable != 0) { LLFixedBuffer::addLine(wline.substr(offset, drawable)); mAddTimes[mAddTimes.size()-1] = line_info.add_time; } else { // force a blank line LLFixedBuffer::addLine(" "); } mColors.push_back(color); offset += (drawable + skip_chars); } } } mLineQueue.clear(); }
// Add the input uuid to the LL clipboard // Convert the uuid to string and concatenate that string to the system clipboard if legit bool LLClipboard::addToClipboard(const LLUUID& src, const LLAssetType::EType type) { bool res = false; if (src.notNull()) { res = true; if (LLAssetType::lookupIsAssetIDKnowable(type)) { LLWString source = utf8str_to_wstring(src.asString()); res = addToClipboard(source, 0, source.size()); } if (res) { mObjects.push_back(src); mGeneration++; } } return res; }
bool LLAutoReplaceSettings::addEntryToList(LLWString keyword, LLWString replacement, std::string listName) { bool added = false; if ( ! keyword.empty() && ! replacement.empty() ) { bool isOneWord = true; for (S32 character = 0; isOneWord && character < keyword.size(); character++ ) { if ( ! LLWStringUtil::isPartOfWord(keyword[character]) ) { LL_WARNS("AutoReplace") << "keyword '" << wstring_to_utf8str(keyword) << "' not a single word (len "<<keyword.size()<<" '"<<character<<"')" << LL_ENDL; isOneWord = false; } } if ( isOneWord ) { bool listFound = false; for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray(); ! listFound && list != endLists; list++ ) { if ( listNameMatches(*list, listName) ) { listFound = true; (*list)[AUTOREPLACE_LIST_REPLACEMENTS][wstring_to_utf8str(keyword)]=wstring_to_utf8str(replacement); } } if (listFound) { added = true; } else { LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL; } } } return added; }
// Walk through a string, applying the rules specified by the keyword token list and // create a list of color segments. void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor) { std::for_each(seg_list->begin(), seg_list->end(), DeletePointer()); seg_list->clear(); if( wtext.empty() ) { return; } S32 text_len = wtext.size(); seg_list->push_back( new LLTextSegment( LLColor3(defaultColor), 0, text_len ) ); const llwchar* base = wtext.c_str(); const llwchar* cur = base; const llwchar* line = NULL; while( *cur ) { if( *cur == '\n' || cur == base ) { if( *cur == '\n' ) { cur++; if( !*cur || *cur == '\n' ) { continue; } } // Start of a new line line = cur; // Skip white space while( *cur && isspace(*cur) && (*cur != '\n') ) { cur++; } if( !*cur || *cur == '\n' ) { continue; } // cur is now at the first non-whitespace character of a new line // Line start tokens { BOOL line_done = FALSE; for (token_list_t::iterator iter = mLineTokenList.begin(); iter != mLineTokenList.end(); ++iter) { LLKeywordToken* cur_token = *iter; if( cur_token->isHead( cur ) ) { S32 seg_start = cur - base; while( *cur && *cur != '\n' ) { // skip the rest of the line cur++; } S32 seg_end = cur - base; LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); text_segment->setToken( cur_token ); insertSegment( seg_list, text_segment, text_len, defaultColor); line_done = TRUE; // to break out of second loop. break; } } if( line_done ) { continue; } } } // Skip white space while( *cur && isspace(*cur) && (*cur != '\n') ) { cur++; } while( *cur && *cur != '\n' ) { // Check against delimiters { S32 seg_start = 0; LLKeywordToken* cur_delimiter = NULL; for (token_list_t::iterator iter = mDelimiterTokenList.begin(); iter != mDelimiterTokenList.end(); ++iter) { LLKeywordToken* delimiter = *iter; if( delimiter->isHead( cur ) ) { cur_delimiter = delimiter; break; } } if( cur_delimiter ) { S32 between_delimiters = 0; S32 seg_end = 0; seg_start = cur - base; cur += cur_delimiter->getLength(); if( cur_delimiter->getType() == LLKeywordToken::TWO_SIDED_DELIMITER ) { while( *cur && !cur_delimiter->isHead(cur)) { // Check for an escape sequence. if (*cur == '\\') { // Count the number of backslashes. S32 num_backslashes = 0; while (*cur == '\\') { num_backslashes++; between_delimiters++; cur++; } // Is the next character the end delimiter? if (cur_delimiter->isHead(cur)) { // Is there was an odd number of backslashes, then this delimiter // does not end the sequence. if (num_backslashes % 2 == 1) { between_delimiters++; cur++; } else { // This is an end delimiter. break; } } } else { between_delimiters++; cur++; } } if( *cur ) { cur += cur_delimiter->getLength(); seg_end = seg_start + between_delimiters + 2 * cur_delimiter->getLength(); } else { // eof seg_end = seg_start + between_delimiters + cur_delimiter->getLength(); } } else { llassert( cur_delimiter->getType() == LLKeywordToken::ONE_SIDED_DELIMITER ); // Left side is the delimiter. Right side is eol or eof. while( *cur && ('\n' != *cur) ) { between_delimiters++; cur++; } seg_end = seg_start + between_delimiters + cur_delimiter->getLength(); } LLTextSegment* text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end ); text_segment->setToken( cur_delimiter ); insertSegment( seg_list, text_segment, text_len, defaultColor); // Note: we don't increment cur, since the end of one delimited seg may be immediately // followed by the start of another one. continue; } } // check against words llwchar prev = cur > base ? *(cur-1) : 0; if( !isalnum( prev ) && (prev != '_') ) { const llwchar* p = cur; while( isalnum( *p ) || (*p == '_') ) { p++; } S32 seg_len = p - cur; if( seg_len > 0 ) { LLWString word( cur, 0, seg_len ); word_token_map_t::iterator map_iter = mWordTokenMap.find(word); if( map_iter != mWordTokenMap.end() ) { LLKeywordToken* cur_token = map_iter->second; S32 seg_start = cur - base; S32 seg_end = seg_start + seg_len; // llinfos << "Seg: [" << word.c_str() << "]" << llendl; LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); text_segment->setToken( cur_token ); insertSegment( seg_list, text_segment, text_len, defaultColor); } cur += seg_len; continue; } } if( *cur && *cur != '\n' ) { cur++; } } } }
LLKeywords::WStringMapIndex::WStringMapIndex(const LLWString& str) { copyData(str.data(), str.size()); }