diff options
-rw-r--r-- | indra/llui/lltextbox.cpp | 15 | ||||
-rw-r--r-- | indra/llui/llurlregistry.cpp | 28 | ||||
-rw-r--r-- | indra/llui/llurlregistry.h | 6 |
3 files changed, 40 insertions, 9 deletions
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index d6ae9e063e..132bef0296 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -302,11 +302,10 @@ LLWString LLTextBox::getWrappedText(const LLStringExplicit& in_text, F32 max_wid // find the next Url in the text string LLUrlMatch match; - while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(wtext), match)) + while ( LLUrlRegistry::instance().findUrl(wtext, match)) { - LLWString wurl = utf8str_to_wstring(match.getUrl()); - S32 start = wtext.find(wurl); - S32 end = start + wurl.size(); + S32 start = match.getStart(); + S32 end = match.getEnd() + 1; // perform word wrap on the text before the Url final_wtext += wrapText(wtext.substr(0, start), hoffset, line_num, max_width); @@ -579,14 +578,14 @@ void LLTextBox::updateDisplayTextAndSegments() LLWString text = mText.getWString(); // find the next Url in the text string - while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(text), match, + while ( LLUrlRegistry::instance().findUrl(text, match, boost::bind(&LLTextBox::onUrlLabelUpdated, this, _1, _2)) ) { // work out the char offset for the start/end of the url - LLWString wurl = utf8str_to_wstring(match.getUrl()); - S32 url_start = text.find(wurl); - S32 url_end = url_start + wurl.size() - 1; + S32 url_start = match.getStart(); + S32 url_end = match.getEnd(); + // and the char offset for the label in the display text S32 seg_start = mDisplayText.size(); S32 start = seg_start + url_start; S32 end = start + match.getLabel().size(); diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index f2d340deb7..6f5c694b1b 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -162,3 +162,31 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL return false; } + +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.getMenuName(), match.getLocation()); + return true; + } + return false; +} diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 84b033036c..85e934e4b5 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -37,10 +37,10 @@ #include "llurlentry.h" #include "llurlmatch.h" #include "llsingleton.h" +#include "llstring.h" #include <string> #include <vector> -#include <map> /// This default callback for findUrl() simply ignores any label updates void LLUrlRegistryNullCallback(const std::string &url, const std::string &label); @@ -77,6 +77,10 @@ public: bool findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback); + /// a slightly less efficient version of findUrl for wide strings + bool findUrl(const LLWString &text, LLUrlMatch &match, + const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback); + private: LLUrlRegistry(); friend class LLSingleton<LLUrlRegistry>; |