diff options
author | maksymsproductengine <maksymsproductengine@lindenlab.com> | 2014-07-10 00:23:01 +0300 |
---|---|---|
committer | maksymsproductengine <maksymsproductengine@lindenlab.com> | 2014-07-10 00:23:01 +0300 |
commit | 58c86cf59ee26dbadd359a28d8b16409c856e966 (patch) | |
tree | 55d22b0f408f7b0bcda4b5dcefb12ff47bcfd286 /indra/llui | |
parent | 70c2472e427c2d58edd857d298ea9f1fbe4bd41f (diff) | |
parent | 226929f8f5b8bc1080d0082b2595d689238df2b8 (diff) |
merge changes for 3.7.12-release
Diffstat (limited to 'indra/llui')
-rwxr-xr-x | indra/llui/llkeywords.cpp | 508 | ||||
-rwxr-xr-x | indra/llui/llkeywords.h | 119 | ||||
-rwxr-xr-x | indra/llui/llnotifications.cpp | 1 | ||||
-rwxr-xr-x | indra/llui/llnotifications.h | 8 | ||||
-rw-r--r-- | indra/llui/llnotificationslistener.cpp | 27 | ||||
-rwxr-xr-x | indra/llui/lltextbase.cpp | 54 | ||||
-rwxr-xr-x | indra/llui/lltextbase.h | 40 | ||||
-rwxr-xr-x | indra/llui/lltexteditor.cpp | 124 | ||||
-rwxr-xr-x | indra/llui/lltexteditor.h | 54 | ||||
-rwxr-xr-x | indra/llui/llxuiparser.cpp | 2 |
10 files changed, 484 insertions, 453 deletions
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index fcd7b274e8..75773d7dfd 100755 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llkeywords.cpp * @brief Keyword list for LSL * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,49 +30,48 @@ #include <fstream> #include "llkeywords.h" +#include "llsdserialize.h" #include "lltexteditor.h" #include "llstl.h" -#include <boost/tokenizer.hpp> - -const U32 KEYWORD_FILE_CURRENT_VERSION = 2; -inline BOOL LLKeywordToken::isHead(const llwchar* s) const +inline bool LLKeywordToken::isHead(const llwchar* s) const { // strncmp is much faster than string compare - BOOL res = TRUE; + bool res = true; const llwchar* t = mToken.c_str(); S32 len = mToken.size(); for (S32 i=0; i<len; i++) { if (s[i] != t[i]) { - res = FALSE; + res = false; break; } } return res; } -LLKeywords::LLKeywords() : mLoaded(FALSE) -{ -} - -inline BOOL LLKeywordToken::isTail(const llwchar* s) const +inline bool LLKeywordToken::isTail(const llwchar* s) const { - BOOL res = TRUE; + bool res = true; const llwchar* t = mDelimiter.c_str(); S32 len = mDelimiter.size(); for (S32 i=0; i<len; i++) { if (s[i] != t[i]) { - res = FALSE; + res = false; break; } } return res; } +LLKeywords::LLKeywords() +: mLoaded(false) +{ +} + LLKeywords::~LLKeywords() { std::for_each(mWordTokenMap.begin(), mWordTokenMap.end(), DeletePairedPointer()); @@ -83,180 +82,307 @@ LLKeywords::~LLKeywords() mDelimiterTokenList.clear(); } -BOOL LLKeywords::loadFromFile( const std::string& filename ) +// Add the token as described +void LLKeywords::addToken(LLKeywordToken::ETokenType type, + const std::string& key_in, + const LLColor4& color, + const std::string& tool_tip_in, + const std::string& delimiter_in) { - mLoaded = FALSE; - - //////////////////////////////////////////////////////////// - // File header - - const S32 BUFFER_SIZE = 1024; - char buffer[BUFFER_SIZE]; /* Flawfinder: ignore */ - - llifstream file; - file.open(filename); /* Flawfinder: ignore */ - if( file.fail() ) + std::string tip_text = tool_tip_in; + LLStringUtil::replaceString(tip_text, "\\n", "\n" ); + LLStringUtil::replaceString(tip_text, "\t", " " ); + if (tip_text.empty()) { - LL_INFOS() << "LLKeywords::loadFromFile() Unable to open file: " << filename << LL_ENDL; - return mLoaded; + tip_text = "[no info]"; } + LLWString tool_tip = utf8str_to_wstring(tip_text); - // Identifying string - file >> buffer; - if( strcmp( buffer, "llkeywords" ) ) - { - LL_INFOS() << filename << " does not appear to be a keyword file" << LL_ENDL; - return mLoaded; - } - - // Check file version - file >> buffer; - U32 version_num; - file >> version_num; - if( strcmp(buffer, "version") || version_num != (U32)KEYWORD_FILE_CURRENT_VERSION ) + LLWString key = utf8str_to_wstring(key_in); + LLWString delimiter = utf8str_to_wstring(delimiter_in); + switch(type) { - LL_INFOS() << filename << " does not appear to be a version " << KEYWORD_FILE_CURRENT_VERSION << " keyword file" << LL_ENDL; - return mLoaded; - } + case LLKeywordToken::TT_CONSTANT: + case LLKeywordToken::TT_CONTROL: + case LLKeywordToken::TT_EVENT: + case LLKeywordToken::TT_FUNCTION: + case LLKeywordToken::TT_LABEL: + case LLKeywordToken::TT_SECTION: + case LLKeywordToken::TT_TYPE: + case LLKeywordToken::TT_WORD: + mWordTokenMap[key] = new LLKeywordToken(type, color, key, tool_tip, LLWStringUtil::null); + break; - // start of line (SOL) - std::string SOL_COMMENT("#"); - std::string SOL_WORD("[word "); - std::string SOL_LINE("[line "); - std::string SOL_ONE_SIDED_DELIMITER("[one_sided_delimiter "); - std::string SOL_TWO_SIDED_DELIMITER("[two_sided_delimiter "); - std::string SOL_DOUBLE_QUOTATION_MARKS("[double_quotation_marks "); + case LLKeywordToken::TT_LINE: + mLineTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, LLWStringUtil::null)); + break; - LLColor3 cur_color( 1, 0, 0 ); - LLKeywordToken::TOKEN_TYPE cur_type = LLKeywordToken::WORD; + case LLKeywordToken::TT_TWO_SIDED_DELIMITER: + case LLKeywordToken::TT_DOUBLE_QUOTATION_MARKS: + case LLKeywordToken::TT_ONE_SIDED_DELIMITER: + mDelimiterTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, delimiter)); + break; - while (!file.eof()) - { - buffer[0] = 0; - file.getline( buffer, BUFFER_SIZE ); - std::string line(buffer); - if( line.find(SOL_COMMENT) == 0 ) - { - continue; - } - else if( line.find(SOL_WORD) == 0 ) - { - cur_color = readColor( line.substr(SOL_WORD.size()) ); - cur_type = LLKeywordToken::WORD; - continue; - } - else if( line.find(SOL_LINE) == 0 ) - { - cur_color = readColor( line.substr(SOL_LINE.size()) ); - cur_type = LLKeywordToken::LINE; - continue; - } - else if( line.find(SOL_TWO_SIDED_DELIMITER) == 0 ) - { - cur_color = readColor( line.substr(SOL_TWO_SIDED_DELIMITER.size()) ); - cur_type = LLKeywordToken::TWO_SIDED_DELIMITER; - continue; - } - else if( line.find(SOL_DOUBLE_QUOTATION_MARKS) == 0 ) - { - cur_color = readColor( line.substr(SOL_DOUBLE_QUOTATION_MARKS.size()) ); - cur_type = LLKeywordToken::DOUBLE_QUOTATION_MARKS; - continue; - } - else if( line.find(SOL_ONE_SIDED_DELIMITER) == 0 ) - { - cur_color = readColor( line.substr(SOL_ONE_SIDED_DELIMITER.size()) ); - cur_type = LLKeywordToken::ONE_SIDED_DELIMITER; - continue; - } + default: + llassert(0); + } +} - std::string token_buffer( line ); - LLStringUtil::trim(token_buffer); - - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep_word("", " \t"); - tokenizer word_tokens(token_buffer, sep_word); - tokenizer::iterator token_word_iter = word_tokens.begin(); +std::string LLKeywords::getArguments(LLSD& arguments) +{ + std::string argString = ""; - if( !token_buffer.empty() && token_word_iter != word_tokens.end() ) + if (arguments.isArray()) + { + U32 argsCount = arguments.size(); + LLSD::array_iterator arrayIt = arguments.beginArray(); + for ( ; arrayIt != arguments.endArray(); ++arrayIt) { - // first word is the keyword or a left delimiter - std::string keyword = (*token_word_iter); - LLStringUtil::trim(keyword); - - // second word may be a right delimiter - std::string delimiter; - if (cur_type == LLKeywordToken::TWO_SIDED_DELIMITER) + LLSD& args = (*arrayIt); + if (args.isMap()) { - while (delimiter.length() == 0 && ++token_word_iter != word_tokens.end()) + LLSD::map_iterator argsIt = args.beginMap(); + for ( ; argsIt != args.endMap(); ++argsIt) { - delimiter = *token_word_iter; - LLStringUtil::trim(delimiter); + argString += argsIt->second.get("type").asString() + " " + argsIt->first; + if (argsCount-- > 1) + { + argString += ", "; + } } } - else if (cur_type == LLKeywordToken::DOUBLE_QUOTATION_MARKS) + else { - // Closing delimiter is identical to the opening one. - delimiter = keyword; + LL_WARNS("SyntaxLSL") << "Argument array comtains a non-map element!" << LL_ENDL; } + } + } + else if (!arguments.isUndefined()) + { + LL_WARNS("SyntaxLSL") << "Not an array! Invalid arguments LLSD passed to function." << arguments << LL_ENDL; + } + return argString; +} - // following words are tooltip - std::string tool_tip; - while (++token_word_iter != word_tokens.end()) - { - tool_tip += (*token_word_iter); - } - LLStringUtil::trim(tool_tip); - - if( !tool_tip.empty() ) +std::string LLKeywords::getAttribute(const std::string& key) +{ + attribute_iterator_t it = mAttributes.find(key); + return (it != mAttributes.end()) ? it->second : ""; +} + +LLColor4 LLKeywords::getColorGroup(const std::string& key_in) +{ + std::string color_group = "ScriptText"; + if (key_in == "functions") + { + color_group = "SyntaxLslFunction"; + } + else if (key_in == "controls") + { + color_group = "SyntaxLslControlFlow"; + } + else if (key_in == "events") + { + color_group = "SyntaxLslEvent"; + } + else if (key_in == "types") + { + color_group = "SyntaxLslDataType"; + } + else if (key_in == "misc-flow-label") + { + color_group = "SyntaxLslControlFlow"; + } + else if (key_in =="deprecated") + { + color_group = "SyntaxLslDeprecated"; + } + else if (key_in =="god-mode") + { + color_group = "SyntaxLslGodMode"; + } + else if (key_in == "constants" + || key_in == "constants-integer" + || key_in == "constants-float" + || key_in == "constants-string" + || key_in == "constants-key" + || key_in == "constants-rotation" + || key_in == "constants-vector") + { + color_group = "SyntaxLslConstant"; + } + else + { + LL_WARNS("SyntaxLSL") << "Color key '" << key_in << "' not recognized." << LL_ENDL; + } + + return LLUIColorTable::instance().getColor(color_group); +} + +void LLKeywords::initialize(LLSD SyntaxXML) +{ + mSyntax = SyntaxXML; + mLoaded = true; +} + +void LLKeywords::processTokens() +{ + if (!mLoaded) + { + return; + } + + // Add 'standard' stuff: Quotes, Comments, Strings, Labels, etc. before processing the LLSD + std::string delimiter; + addToken(LLKeywordToken::TT_LABEL, "@", getColorGroup("misc-flow-label"), "Label\nTarget for jump statement", delimiter ); + addToken(LLKeywordToken::TT_ONE_SIDED_DELIMITER, "//", LLUIColorTable::instance().getColor("SyntaxLslComment"), "Comment (single-line)\nNon-functional commentary or disabled code", delimiter ); + addToken(LLKeywordToken::TT_TWO_SIDED_DELIMITER, "/*", LLUIColorTable::instance().getColor("SyntaxLslComment"), "Comment (multi-line)\nNon-functional commentary or disabled code", "*/" ); + addToken(LLKeywordToken::TT_DOUBLE_QUOTATION_MARKS, "\"", LLUIColorTable::instance().getColor("SyntaxLslStringLiteral"), "String literal", "\"" ); + + LLSD::map_iterator itr = mSyntax.beginMap(); + for ( ; itr != mSyntax.endMap(); ++itr) + { + if (itr->first == "llsd-lsl-syntax-version") + { + // Skip over version key. + } + else + { + if (itr->second.isMap()) { - // Replace : with \n for multi-line tool tips. - LLStringUtil::replaceChar( tool_tip, ':', '\n' ); - addToken(cur_type, keyword, cur_color, tool_tip, delimiter ); + processTokensGroup(itr->second, itr->first); } else { - addToken(cur_type, keyword, cur_color, LLStringUtil::null, delimiter ); + LL_WARNS("LSL-Tokens-Processing") << "Map for " + itr->first + " entries is missing! Ignoring." << LL_ENDL; } } } - - file.close(); - - mLoaded = TRUE; - return mLoaded; + LL_INFOS("SyntaxLSL") << "Finished processing tokens." << LL_ENDL; } -// Add the token as described -void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type, - const std::string& key_in, - const LLColor3& color, - const std::string& tool_tip_in, - const std::string& delimiter_in) +void LLKeywords::processTokensGroup(const LLSD& tokens, const std::string& group) { - LLWString key = utf8str_to_wstring(key_in); - LLWString tool_tip = utf8str_to_wstring(tool_tip_in); - LLWString delimiter = utf8str_to_wstring(delimiter_in); - switch(type) + LLColor4 color; + LLColor4 color_group; + LLColor4 color_deprecated = getColorGroup("deprecated"); + LLColor4 color_god_mode = getColorGroup("god-mode"); + + LLKeywordToken::ETokenType token_type = LLKeywordToken::TT_UNKNOWN; + // If a new token type is added here, it must also be added to the 'addToken' method + if (group == "constants") { - case LLKeywordToken::WORD: - mWordTokenMap[key] = new LLKeywordToken(type, color, key, tool_tip, LLWStringUtil::null); - break; + token_type = LLKeywordToken::TT_CONSTANT; + } + else if (group == "controls") + { + token_type = LLKeywordToken::TT_CONTROL; + } + else if (group == "events") + { + token_type = LLKeywordToken::TT_EVENT; + } + else if (group == "functions") + { + token_type = LLKeywordToken::TT_FUNCTION; + } + else if (group == "label") + { + token_type = LLKeywordToken::TT_LABEL; + } + else if (group == "types") + { + token_type = LLKeywordToken::TT_TYPE; + } - case LLKeywordToken::LINE: - mLineTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, LLWStringUtil::null)); - break; + color_group = getColorGroup(group); + LL_INFOS("SyntaxLSL") << "Group: '" << group << "', using color: '" << color_group << "'" << LL_ENDL; - case LLKeywordToken::TWO_SIDED_DELIMITER: - case LLKeywordToken::DOUBLE_QUOTATION_MARKS: - case LLKeywordToken::ONE_SIDED_DELIMITER: - mDelimiterTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, delimiter)); - break; + if (tokens.isMap()) + { + LLSD::map_const_iterator outer_itr = tokens.beginMap(); + for ( ; outer_itr != tokens.endMap(); ++outer_itr ) + { + if (outer_itr->second.isMap()) + { + mAttributes.clear(); + LLSD arguments = LLSD(); + LLSD::map_const_iterator inner_itr = outer_itr->second.beginMap(); + for ( ; inner_itr != outer_itr->second.endMap(); ++inner_itr ) + { + if (inner_itr->first == "arguments") + { + if (inner_itr->second.isArray()) + { + arguments = inner_itr->second; + } + } + else if (!inner_itr->second.isMap() && !inner_itr->second.isArray()) + { + mAttributes[inner_itr->first] = inner_itr->second.asString(); + } + else + { + LL_WARNS("SyntaxLSL") << "Not a valid attribute: " << inner_itr->first << LL_ENDL; + } + } - default: - llassert(0); + std::string tooltip = ""; + switch (token_type) + { + case LLKeywordToken::TT_CONSTANT: + color_group = getColorGroup(group + "-" + getAttribute("type")); + tooltip = "Type: " + getAttribute("type") + ", Value: " + getAttribute("value"); + break; + case LLKeywordToken::TT_EVENT: + tooltip = outer_itr->first + "(" + getArguments(arguments) + ")"; + break; + case LLKeywordToken::TT_FUNCTION: + tooltip = getAttribute("return") + " " + outer_itr->first + "(" + getArguments(arguments) + ");"; + tooltip.append("\nEnergy: "); + tooltip.append(getAttribute("energy").empty() ? "0.0" : getAttribute("energy")); + if (!getAttribute("sleep").empty()) + { + tooltip += ", Sleep: " + getAttribute("sleep"); + } + default: + break; + } + + if (!getAttribute("tooltip").empty()) + { + if (!tooltip.empty()) + { + tooltip.append("\n"); + } + tooltip.append(getAttribute("tooltip")); + } + + color = getAttribute("deprecated") == "true" ? color_deprecated : color_group; + + if (getAttribute("god-mode") == "true") + { + color = color_god_mode; + } + + addToken(token_type, outer_itr->first, color, tooltip); + } + } + } + else if (tokens.isArray()) // Currently nothing should need this, but it's here for completeness + { + LL_INFOS("SyntaxLSL") << "Curious, shouldn't be an array here; adding all using color " << color << LL_ENDL; + for (S32 count = 0; count < tokens.size(); ++count) + { + addToken(token_type, tokens[count], color, ""); + } + } + else + { + LL_WARNS("SyntaxLSL") << "Invalid map/array passed: '" << tokens << "'" << LL_ENDL; } } + LLKeywords::WStringMapIndex::WStringMapIndex(const WStringMapIndex& other) { if(other.mOwner) @@ -276,15 +402,19 @@ LLKeywords::WStringMapIndex::WStringMapIndex(const LLWString& str) copyData(str.data(), str.size()); } -LLKeywords::WStringMapIndex::WStringMapIndex(const llwchar *start, size_t length): -mData(start), mLength(length), mOwner(false) +LLKeywords::WStringMapIndex::WStringMapIndex(const llwchar *start, size_t length) +: mData(start) +, mLength(length) +, mOwner(false) { } LLKeywords::WStringMapIndex::~WStringMapIndex() { - if(mOwner) + if (mOwner) + { delete[] mData; + } } void LLKeywords::WStringMapIndex::copyData(const llwchar *start, size_t length) @@ -301,13 +431,13 @@ bool LLKeywords::WStringMapIndex::operator<(const LLKeywords::WStringMapIndex &o { // NOTE: Since this is only used to organize a std::map, it doesn't matter if it uses correct collate order or not. // The comparison only needs to strictly order all possible strings, and be stable. - + bool result = false; const llwchar* self_iter = mData; const llwchar* self_end = mData + mLength; const llwchar* other_iter = other.mData; const llwchar* other_end = other.mData + other.mLength; - + while(true) { if(other_iter >= other_end) @@ -322,7 +452,7 @@ bool LLKeywords::WStringMapIndex::operator<(const LLKeywords::WStringMapIndex &o { // self is shorter than other. result = true; - break; + break; } else if(*self_iter != *other_iter) { @@ -334,20 +464,8 @@ bool LLKeywords::WStringMapIndex::operator<(const LLKeywords::WStringMapIndex &o self_iter++; other_iter++; } - - return result; -} -LLColor3 LLKeywords::readColor( const std::string& s ) -{ - F32 r, g, b; - r = g = b = 0.0f; - S32 values_read = sscanf(s.c_str(), "%f, %f, %f]", &r, &g, &b ); - if( values_read != 3 ) - { - LL_INFOS() << " poorly formed color in keyword file" << LL_ENDL; - } - return LLColor3( r, g, b ); + return result; } LLTrace::BlockTimerStatHandle FTM_SYNTAX_COLORING("Syntax Coloring"); @@ -363,10 +481,10 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW { return; } - + S32 text_len = wtext.size() + 1; - seg_list->push_back( new LLNormalTextSegment( defaultColor, 0, text_len, editor ) ); + seg_list->push_back( new LLNormalTextSegment( defaultColor, 0, text_len, editor ) ); const llwchar* base = wtext.c_str(); const llwchar* cur = base; @@ -396,7 +514,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW continue; } - // cur is now at the first non-whitespace character of a new line + // cur is now at the first non-whitespace character of a new line // Line start tokens { @@ -414,7 +532,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW cur++; } S32 seg_end = cur - base; - + //create segments from seg_start to seg_end insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor); line_done = TRUE; // to break out of second loop. @@ -459,14 +577,14 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW seg_start = cur - base; cur += cur_delimiter->getLengthHead(); - - LLKeywordToken::TOKEN_TYPE type = cur_delimiter->getType(); - if( type == LLKeywordToken::TWO_SIDED_DELIMITER || type == LLKeywordToken::DOUBLE_QUOTATION_MARKS ) + + LLKeywordToken::ETokenType type = cur_delimiter->getType(); + if( type == LLKeywordToken::TT_TWO_SIDED_DELIMITER || type == LLKeywordToken::TT_DOUBLE_QUOTATION_MARKS ) { while( *cur && !cur_delimiter->isTail(cur)) { // Check for an escape sequence. - if (type == LLKeywordToken::DOUBLE_QUOTATION_MARKS && *cur == '\\') + if (type == LLKeywordToken::TT_DOUBLE_QUOTATION_MARKS && *cur == '\\') { // Count the number of backslashes. S32 num_backslashes = 0; @@ -513,7 +631,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW } else { - llassert( cur_delimiter->getType() == LLKeywordToken::ONE_SIDED_DELIMITER ); + llassert( cur_delimiter->getType() == LLKeywordToken::TT_ONE_SIDED_DELIMITER ); // Left side is the delimiter. Right side is eol or eof. while( *cur && ('\n' != *cur) ) { @@ -555,11 +673,11 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW S32 seg_start = cur - base; S32 seg_end = seg_start + seg_len; - // LL_INFOS() << "Seg: [" << word.c_str() << "]" << LL_ENDL; + // llinfos << "Seg: [" << word.c_str() << "]" << llendl; insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor); } - cur += seg_len; + cur += seg_len; continue; } } @@ -575,7 +693,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor ) { std::string::size_type pos = wtext.find('\n',seg_start); - + while (pos!=-1 && pos < (std::string::size_type)seg_end) { if (pos!=seg_start) @@ -622,10 +740,10 @@ void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSe #ifdef _DEBUG void LLKeywords::dump() { - LL_INFOS() << "LLKeywords" << LL_ENDL; + llinfos << "LLKeywords" << llendl; - LL_INFOS() << "LLKeywords::sWordTokenMap" << LL_ENDL; + llinfos << "LLKeywords::sWordTokenMap" << llendl; word_token_map_t::iterator word_token_iter = mWordTokenMap.begin(); while( word_token_iter != mWordTokenMap.end() ) { @@ -634,7 +752,7 @@ void LLKeywords::dump() ++word_token_iter; } - LL_INFOS() << "LLKeywords::sLineTokenList" << LL_ENDL; + llinfos << "LLKeywords::sLineTokenList" << llendl; for (token_list_t::iterator iter = mLineTokenList.begin(); iter != mLineTokenList.end(); ++iter) { @@ -643,7 +761,7 @@ void LLKeywords::dump() } - LL_INFOS() << "LLKeywords::sDelimiterTokenList" << LL_ENDL; + llinfos << "LLKeywords::sDelimiterTokenList" << llendl; for (token_list_t::iterator iter = mDelimiterTokenList.begin(); iter != mDelimiterTokenList.end(); ++iter) { @@ -654,12 +772,12 @@ void LLKeywords::dump() void LLKeywordToken::dump() { - LL_INFOS() << "[" << + llinfos << "[" << mColor.mV[VX] << ", " << mColor.mV[VY] << ", " << mColor.mV[VZ] << "] [" << wstring_to_utf8str(mToken) << "]" << - LL_ENDL; + llendl; } #endif // DEBUG diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index ac34015393..18e2ed06c5 100755 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -1,25 +1,25 @@ -/** +/** * @file llkeywords.h * @brief Keyword list for LSL * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,8 +28,10 @@ #define LL_LLKEYWORDS_H +#include "lldir.h" #include "llstring.h" #include "v3color.h" +#include "v4color.h" #include <map> #include <list> #include <deque> @@ -41,26 +43,35 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr; class LLKeywordToken { public: - /** + /** * @brief Types of tokens/delimters being parsed. * * @desc Tokens/delimiters that need to be identified/highlighted. All are terminated if an EOF is encountered. - * - WORD are keywords in the normal sense, i.e. constants, events, etc. - * - LINE are for entire lines (currently only flow control labels use this). - * - ONE_SIDED_DELIMITER are for open-ended delimiters which are terminated by EOL. - * - TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with. - * - DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close. + * - TT_WORD are keywords in the normal sense, i.e. constants, events, etc. + * - TT_LINE are for entire lines (currently only flow control labels use this). + * - TT_ONE_SIDED_DELIMITER are for open-ended delimiters which are terminated by EOL. + * - TT_TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with. + * - TT_DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close. */ - enum TOKEN_TYPE + typedef enum e_token_type { - WORD, - LINE, - TWO_SIDED_DELIMITER, - ONE_SIDED_DELIMITER, - DOUBLE_QUOTATION_MARKS - }; - - LLKeywordToken( TOKEN_TYPE type, const LLColor3& color, const LLWString& token, const LLWString& tool_tip, const LLWString& delimiter ) + TT_UNKNOWN, + TT_WORD, + TT_LINE, + TT_TWO_SIDED_DELIMITER, + TT_ONE_SIDED_DELIMITER, + TT_DOUBLE_QUOTATION_MARKS, + // Following constants are more specific versions of the preceding ones + TT_CONSTANT, // WORD + TT_CONTROL, // WORD + TT_EVENT, // WORD + TT_FUNCTION, // WORD + TT_LABEL, // LINE + TT_SECTION, // WORD + TT_TYPE // WORD + } ETokenType; + + LLKeywordToken( ETokenType type, const LLColor4& color, const LLWString& token, const LLWString& tool_tip, const LLWString& delimiter ) : mType( type ), mToken( token ), @@ -72,11 +83,11 @@ public: S32 getLengthHead() const { return mToken.size(); } S32 getLengthTail() const { return mDelimiter.size(); } - BOOL isHead(const llwchar* s) const; - BOOL isTail(const llwchar* s) const; + bool isHead(const llwchar* s) const; + bool isTail(const llwchar* s) const; const LLWString& getToken() const { return mToken; } - const LLColor3& getColor() const { return mColor; } - TOKEN_TYPE getType() const { return mType; } + const LLColor4& getColor() const { return mColor; } + ETokenType getType() const { return mType; } const LLWString& getToolTip() const { return mToolTip; } const LLWString& getDelimiter() const { return mDelimiter; } @@ -85,9 +96,9 @@ public: #endif private: - TOKEN_TYPE mType; + ETokenType mType; LLWString mToken; - LLColor3 mColor; + LLColor4 mColor; LLWString mToolTip; LLWString mDelimiter; }; @@ -98,18 +109,24 @@ public: LLKeywords(); ~LLKeywords(); - BOOL loadFromFile(const std::string& filename); - BOOL isLoaded() const { return mLoaded; } + void clearLoaded() { mLoaded = false; } + LLColor4 getColorGroup(const std::string& key_in); + bool isLoaded() const { return mLoaded; } - void findSegments(std::vector<LLTextSegmentPtr> *seg_list, const LLWString& text, const LLColor4 &defaultColor, class LLTextEditor& editor ); + void findSegments(std::vector<LLTextSegmentPtr> *seg_list, + const LLWString& text, + const LLColor4 &defaultColor, + class LLTextEditor& editor); + void initialize(LLSD SyntaxXML); + void processTokens(); // Add the token as described - void addToken(LLKeywordToken::TOKEN_TYPE type, + void addToken(LLKeywordToken::ETokenType type, const std::string& key, - const LLColor3& color, + const LLColor4& color, const std::string& tool_tip = LLStringUtil::null, const std::string& delimiter = LLStringUtil::null); - + // This class is here as a performance optimization. // The word token map used to be defined as std::map<LLWString, LLKeywordToken*>. // This worked, but caused a performance bottleneck due to memory allocation and string copies @@ -133,6 +150,9 @@ public: const llwchar *mData; size_t mLength; bool mOwner; + + + LLColor4 mColor; }; typedef std::map<WStringMapIndex, LLKeywordToken*> word_token_map_t; @@ -140,20 +160,43 @@ public: keyword_iterator_t begin() const { return mWordTokenMap.begin(); } keyword_iterator_t end() const { return mWordTokenMap.end(); } + typedef std::map<WStringMapIndex, LLColor4> group_color_map_t; + typedef group_color_map_t::const_iterator color_iterator_t; + group_color_map_t mColorGroupMap; + #ifdef _DEBUG void dump(); #endif -private: - LLColor3 readColor(const std::string& s); - void insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, class LLTextEditor& editor); - void insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor); - - BOOL mLoaded; +protected: + void processTokensGroup(const LLSD& Tokens, const std::string& Group); + void insertSegment(std::vector<LLTextSegmentPtr>& seg_list, + LLTextSegmentPtr new_segment, + S32 text_len, + const LLColor4 &defaultColor, + class LLTextEditor& editor); + void insertSegments(const LLWString& wtext, + std::vector<LLTextSegmentPtr>& seg_list, + LLKeywordToken* token, + S32 text_len, + S32 seg_start, + S32 seg_end, + const LLColor4 &defaultColor, + LLTextEditor& editor); + + bool mLoaded; + LLSD mSyntax; word_token_map_t mWordTokenMap; typedef std::deque<LLKeywordToken*> token_list_t; token_list_t mLineTokenList; token_list_t mDelimiterTokenList; + + typedef std::map<std::string, std::string> element_attributes_t; + typedef element_attributes_t::const_iterator attribute_iterator_t; + element_attributes_t mAttributes; + std::string getAttribute(const std::string& key); + + std::string getArguments(LLSD& arguments); }; #endif // LL_LLKEYWORDS_H diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 025cd81d92..de14391d1f 100755 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1189,6 +1189,7 @@ void LLNotificationChannel::connectToChannel( const std::string& channel_name ) } else { + mParents.push_back(channel_name); LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name); p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index b0e8553a49..3cf432f330 100755 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -88,6 +88,7 @@ #include <boost/enable_shared_from_this.hpp> #include <boost/type_traits.hpp> #include <boost/signals2.hpp> +#include <boost/range.hpp> #include "llevents.h" #include "llfunctorregistry.h" @@ -840,6 +841,11 @@ public: typedef LLNotificationSet::iterator Iterator; std::string getName() const { return mName; } + typedef std::vector<std::string>::const_iterator parents_iter; + boost::iterator_range<parents_iter> getParents() const + { + return boost::iterator_range<parents_iter>(mParents); + } void connectToChannel(const std::string& channel_name); @@ -854,7 +860,7 @@ public: private: std::string mName; - std::string mParent; + std::vector<std::string> mParents; }; // An interface class to provide a clean linker seam to the LLNotifications class. diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp index 9e8e943ee6..b6a32a0e78 100644 --- a/indra/llui/llnotificationslistener.cpp +++ b/indra/llui/llnotificationslistener.cpp @@ -32,6 +32,7 @@ #include "llnotificationtemplate.h" #include "llsd.h" #include "llui.h" +#include <boost/foreach.hpp> LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) : LLEventAPI("LLNotifications", @@ -42,11 +43,10 @@ LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n" "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.", &LLNotificationsListener::requestAdd); - /* add("listChannels", + add("listChannels", "Post to [\"reply\"] a map of info on existing channels", &LLNotificationsListener::listChannels, LLSD().with("reply", LLSD())); - */ add("listChannelNotifications", "Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]", &LLNotificationsListener::listChannelNotifications, @@ -117,26 +117,27 @@ void LLNotificationsListener::NotificationResponder(const std::string& reply_pum reponse_event["response"] = response; LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event); } -/* + void LLNotificationsListener::listChannels(const LLSD& params) const { LLReqID reqID(params); LLSD response(reqID.makeResponse()); - for (LLNotifications:: - - - - for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()), - cmend(mNotifications.mChannels.end()); + for (LLNotificationChannel::instance_iter cmi(LLNotificationChannel::beginInstances()), + cmend(LLNotificationChannel::endInstances()); cmi != cmend; ++cmi) { - LLSD channelInfo; - channelInfo["parent"] = cmi->second->getParentChannelName(); - response[cmi->first] = channelInfo; + LLSD channelInfo, parents; + BOOST_FOREACH(const std::string& parent, cmi->getParents()) + { + parents.append(parent); + } + channelInfo["parents"] = parents; + channelInfo["parent"] = parents.size()? parents[0] : ""; + response[cmi->getName()] = channelInfo; } LLEventPumps::instance().obtain(params["reply"]).post(response); } -*/ + void LLNotificationsListener::listChannelNotifications(const LLSD& params) const { LLReqID reqID(params); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8906a6e736..71db0ac030 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -70,43 +70,36 @@ bool LLTextBase::compare_segment_end::operator()(const LLTextSegmentPtr& a, cons // helper functors -struct LLTextBase::compare_bottom +bool LLTextBase::compare_bottom::operator()(const S32& a, const LLTextBase::line_info& b) const { - bool operator()(const S32& a, const LLTextBase::line_info& b) const - { - return a > b.mRect.mBottom; // bottom of a is higher than bottom of b - } - - bool operator()(const LLTextBase::line_info& a, const S32& b) const - { - return a.mRect.mBottom > b; // bottom of a is higher than bottom of b - } + return a > b.mRect.mBottom; // bottom of a is higher than bottom of b +} - bool operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const - { - return a.mRect.mBottom > b.mRect.mBottom; // bottom of a is higher than bottom of b - } +bool LLTextBase::compare_bottom::operator()(const LLTextBase::line_info& a, const S32& b) const +{ + return a.mRect.mBottom > b; // bottom of a is higher than bottom of b +} -}; +bool LLTextBase::compare_bottom::operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const +{ + return a.mRect.mBottom > b.mRect.mBottom; // bottom of a is higher than bottom of b +} // helper functors -struct LLTextBase::compare_top +bool LLTextBase::compare_top::operator()(const S32& a, const LLTextBase::line_info& b) const { - bool operator()(const S32& a, const LLTextBase::line_info& b) const - { - return a > b.mRect.mTop; // top of a is higher than top of b - } + return a > b.mRect.mTop; // top of a is higher than top of b +} - bool operator()(const LLTextBase::line_info& a, const S32& b) const - { - return a.mRect.mTop > b; // top of a is higher than top of b - } +bool LLTextBase::compare_top::operator()(const LLTextBase::line_info& a, const S32& b) const +{ + return a.mRect.mTop > b; // top of a is higher than top of b +} - bool operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const - { - return a.mRect.mTop > b.mRect.mTop; // top of a is higher than top of b - } -}; +bool LLTextBase::compare_top::operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const +{ + return a.mRect.mTop > b.mRect.mTop; // top of a is higher than top of b +} struct LLTextBase::line_end_compare { @@ -573,7 +566,8 @@ void LLTextBase::drawText() if ( (getSpellCheck()) && (getWText().length() > 2) ) { // Calculate start and end indices for the spell checking range - S32 start = line_start, end = getLineEnd(last_line); + S32 start = line_start; + S32 end = getLineEnd(last_line); if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) ) { diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index ecbfdaf84c..738b4d5b8e 100755 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -451,9 +451,31 @@ public: LLScrollContainer* getScrollContainer() const { return mScroller; } protected: + // protected member variables + // List of offsets and segment index of the start of each line. Always has at least one node (0). + struct line_info + { + line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num); + S32 mDocIndexStart; + S32 mDocIndexEnd; + LLRect mRect; + S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap) + }; + typedef std::vector<line_info> line_list_t; + // helper structs - struct compare_bottom; - struct compare_top; + struct compare_bottom + { + bool operator()(const S32& a, const line_info& b) const; + bool operator()(const line_info& a, const S32& b) const; + bool operator()(const line_info& a, const line_info& b) const; + }; + struct compare_top + { + bool operator()(const S32& a, const line_info& b) const; + bool operator()(const line_info& a, const S32& b) const; + bool operator()(const line_info& a, const line_info& b) const; + }; struct line_end_compare; typedef std::vector<LLTextSegmentPtr> segment_vec_t; @@ -501,18 +523,6 @@ protected: }; typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t; - // protected member variables - // List of offsets and segment index of the start of each line. Always has at least one node (0). - struct line_info - { - line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num); - S32 mDocIndexStart; - S32 mDocIndexEnd; - LLRect mRect; - S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap) - }; - typedef std::vector<line_info> line_list_t; - // member functions LLTextBase(const Params &p); virtual ~LLTextBase(); @@ -522,7 +532,7 @@ protected: virtual bool useLabel() const; // draw methods - void drawSelectionBackground(); // draws the black box behind the selected text + virtual void drawSelectionBackground(); // draws the black box behind the selected text void drawCursor(); void drawText(); diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index b4ebed0849..90e3606998 100755 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -75,8 +75,6 @@ template class LLTextEditor* LLView::getChild<class LLTextEditor>( // // Constants // -const S32 UI_TEXTEDITOR_LINE_NUMBER_MARGIN = 32; -const S32 UI_TEXTEDITOR_LINE_NUMBER_DIGITS = 4; const S32 SPACES_PER_TAB = 4; const F32 SPELLCHECK_DELAY = 0.5f; // delay between the last keypress and spell checking the word the cursor is on @@ -236,7 +234,6 @@ LLTextEditor::Params::Params() prevalidate_callback("prevalidate_callback"), embedded_items("embedded_items", false), ignore_tab("ignore_tab", true), - show_line_numbers("show_line_numbers", false), auto_indent("auto_indent", true), default_color("default_color"), commit_on_focus_lost("commit_on_focus_lost", false), @@ -252,8 +249,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : mBaseDocIsPristine(TRUE), mPristineCmd( NULL ), mLastCmd( NULL ), - mDefaultColor( p.default_color() ), - mShowLineNumbers ( p.show_line_numbers ), + mDefaultColor( p.default_color() ), mAutoIndent(p.auto_indent), mCommitOnFocusLost( p.commit_on_focus_lost), mAllowEmbeddedItems( p.embedded_items ), @@ -277,14 +273,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : params.visible = p.border_visible; mBorder = LLUICtrlFactory::create<LLViewBorder> (params); addChild( mBorder ); - setText(p.default_text()); - - if (mShowLineNumbers) - { - mHPad += UI_TEXTEDITOR_LINE_NUMBER_MARGIN; - updateRects(); - } mParseOnTheFly = TRUE; } @@ -2197,69 +2186,6 @@ void LLTextEditor::drawPreeditMarker() } } - -void LLTextEditor::drawLineNumbers() -{ - LLGLSUIDefault gls_ui; - LLRect scrolled_view_rect = getVisibleDocumentRect(); - LLRect content_rect = getVisibleTextRect(); - LLLocalClipRect clip(content_rect); - S32 first_line = getFirstVisibleLine(); - S32 num_lines = getLineCount(); - if (first_line >= num_lines) - { - return; - } - - S32 cursor_line = mLineInfoList[getLineNumFromDocIndex(mCursorPos)].mLineNum; - - if (mShowLineNumbers) - { - S32 left = 0; - S32 top = getRect().getHeight(); - S32 bottom = 0; - - gl_rect_2d(left, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN, bottom, mReadOnlyBgColor.get() ); // line number area always read-only - gl_rect_2d(UI_TEXTEDITOR_LINE_NUMBER_MARGIN, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN-1, bottom, LLColor4::grey3); // separator - - S32 last_line_num = -1; - - for (S32 cur_line = first_line; cur_line < num_lines; cur_line++) - { - line_info& line = mLineInfoList[cur_line]; - - if ((line.mRect.mTop - scrolled_view_rect.mBottom) < mVisibleTextRect.mBottom) - { - break; - } - - S32 line_bottom = line.mRect.mBottom - scrolled_view_rect.mBottom + mVisibleTextRect.mBottom; - // draw the line numbers - if(line.mLineNum != last_line_num && line.mRect.mTop <= scrolled_view_rect.mTop) - { - const LLFontGL *num_font = LLFontGL::getFontMonospace(); - const LLWString ltext = utf8str_to_wstring(llformat("%d", line.mLineNum )); - BOOL is_cur_line = cursor_line == line.mLineNum; - const U8 style = is_cur_line ? LLFontGL::BOLD : LLFontGL::NORMAL; - const LLColor4 fg_color = is_cur_line ? mCursorColor : mReadOnlyFgColor; - num_font->render( - ltext, // string to draw - 0, // begin offset - UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2, // x - line_bottom, // y - fg_color, - LLFontGL::RIGHT, // horizontal alignment - LLFontGL::BOTTOM, // vertical alignment - style, - LLFontGL::NO_SHADOW, - S32_MAX, // max chars - UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2); // max pixels - last_line_num = line.mLineNum; - } - } - } -} - void LLTextEditor::draw() { { @@ -2271,7 +2197,6 @@ void LLTextEditor::draw() } LLTextBase::draw(); - drawLineNumbers(); drawPreeditMarker(); @@ -2513,53 +2438,6 @@ BOOL LLTextEditor::tryToRevertToPristineState() return isPristine(); // TRUE => success } - -static LLTrace::BlockTimerStatHandle FTM_SYNTAX_HIGHLIGHTING("Syntax Highlighting"); -void LLTextEditor::loadKeywords(const std::string& filename, - const std::vector<std::string>& funcs, - const std::vector<std::string>& tooltips, - const LLColor3& color) -{ - LL_RECORD_BLOCK_TIME(FTM_SYNTAX_HIGHLIGHTING); - if(mKeywords.loadFromFile(filename)) - { - S32 count = llmin(funcs.size(), tooltips.size()); - for(S32 i = 0; i < count; i++) - { - std::string name = utf8str_trim(funcs[i]); - mKeywords.addToken(LLKeywordToken::WORD, name, color, tooltips[i] ); - } - segment_vec_t segment_list; - mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this); - - mSegments.clear(); - segment_set_t::iterator insert_it = mSegments.begin(); - for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it) - { - insert_it = mSegments.insert(insert_it, *list_it); - } - } -} - -void LLTextEditor::updateSegments() -{ - if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly) - { - LL_RECORD_BLOCK_TIME(FTM_SYNTAX_HIGHLIGHTING); - // HACK: No non-ascii keywords for now - segment_vec_t segment_list; - mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this); - - clearSegments(); - for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it) - { - insertSegment(*list_it); - } - } - - LLTextBase::updateSegments(); -} - void LLTextEditor::updateLinkSegments() { LLWString wtext = getWText(); diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 3a96d8ed24..2408613824 100755 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -1,25 +1,25 @@ -/** +/** * @file lltexteditor.h * @brief LLTextEditor base class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,7 +30,6 @@ #define LL_LLTEXTEDITOR_H #include "llrect.h" -#include "llkeywords.h" #include "llframetimer.h" #include "llstyle.h" #include "lleditmenuhandler.h" @@ -43,7 +42,6 @@ class LLFontGL; class LLScrollbar; -class LLKeywordToken; class TextCmd; class LLUICtrlFactory; class LLScrollContainer; @@ -60,7 +58,6 @@ public: Optional<bool> embedded_items, ignore_tab, - show_line_numbers, commit_on_focus_lost, show_context_menu, enable_tooltip_paste, @@ -131,7 +128,7 @@ public: virtual BOOL canCopy() const; virtual void paste(); virtual BOOL canPaste() const; - + virtual void updatePrimary(); virtual void copyPrimary(); virtual void pastePrimary(); @@ -149,7 +146,7 @@ public: void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); - + // Undo/redo stack void blockUndo(); @@ -186,13 +183,6 @@ public: void getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap ); - void loadKeywords(const std::string& filename, - const std::vector<std::string>& funcs, - const std::vector<std::string>& tooltips, - const LLColor3& func_color); - LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); } - LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); } - // Hacky methods to make it into a word-wrapping, potentially scrolling, // read-only text box. void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; } @@ -204,7 +194,7 @@ public: const LLUUID& getSourceID() const { return mSourceID; } const LLTextSegmentPtr getPreviousSegment() const; - void getSelectedSegments(segment_vec_t& segments) const; + void getSelectedSegments(segment_vec_t& segments) const; void setShowContextMenu(bool show) { mShowContextMenu = show; } bool getShowContextMenu() const { return mShowContextMenu; } @@ -216,7 +206,7 @@ protected: void drawPreeditMarker(); void assignEmbedded(const std::string &s); - + void removeCharOrTab(); void indentSelectedLines( S32 spaces ); @@ -235,12 +225,12 @@ protected: S32 nextWordPos(S32 cursorPos) const; void autoIndent(); - + void findEmbeddedItemSegments(S32 start, S32 end); void getSegmentsInRange(segment_vec_t& segments, S32 start, S32 end, bool include_partial) const; virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; } - + // Here's the method that takes and applies text commands. S32 execute(TextCmd* cmd); @@ -254,7 +244,7 @@ protected: S32 removeChar(S32 pos); S32 insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment); S32 remove(S32 pos, S32 length, bool group_with_next_op); - + void focusLostHelper(); void updateAllowingLanguageInput(); BOOL hasPreeditString() const; @@ -272,14 +262,14 @@ protected: // // Protected data // - // Probably deserves serious thought to hiding as many of these + // Probably deserves serious thought to hiding as many of these // as possible behind protected accessor methods. // // Use these to determine if a click on an embedded item is a drag or not. S32 mMouseDownX; S32 mMouseDownY; - + LLWString mPreeditWString; LLWString mPreeditOverwrittenWString; std::vector<S32> mPreeditPositions; @@ -288,11 +278,11 @@ protected: protected: LLUIColor mDefaultColor; - BOOL mShowLineNumbers; bool mAutoIndent; + bool mParseOnTheFly; - /*virtual*/ void updateSegments(); void updateLinkSegments(); + class LLViewBorder* mBorder; private: // @@ -302,23 +292,14 @@ private: void cleanStringForPaste(LLWString & clean_string); void pasteTextWithLinebreaks(LLWString & clean_string); - void drawLineNumbers(); - void onKeyStroke(); - // - // Data - // - LLKeywords mKeywords; - // Concrete TextCmd sub-classes used by the LLTextEditor base class class TextCmdInsert; class TextCmdAddChar; class TextCmdOverwriteChar; class TextCmdRemove; - class LLViewBorder* mBorder; - BOOL mBaseDocIsPristine; TextCmd* mPristineCmd; @@ -333,7 +314,6 @@ private: BOOL mAllowEmbeddedItems; bool mShowContextMenu; - bool mParseOnTheFly; bool mEnableTooltipPaste; bool mPassDelete; @@ -353,4 +333,4 @@ extern template class LLTextEditor* LLView::getChild<class LLTextEditor>( const std::string& name, BOOL recurse) const; #endif -#endif // LL_TEXTEDITOR_ +#endif // LL_TEXTEDITOR_H diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index 4390ca83e9..37d88cb9f9 100755 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -30,7 +30,7 @@ #include "llxmlnode.h" #include "llfasttimer.h" -#ifdef LL_STANDALONE +#ifdef LL_USESYSTEMLIBS #include <expat.h> #else #include "expat/expat.h" |