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;
					}
				}
			}
		}
	}
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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();
}
예제 #7
0
// 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;
}
예제 #9
0
// 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++;
			}
		}
	}
}
예제 #10
0
LLKeywords::WStringMapIndex::WStringMapIndex(const LLWString& str)
{
	copyData(str.data(), str.size());
}