From 536e38ad51b89808f26d8e3cd107fe093862d22a Mon Sep 17 00:00:00 2001 From: David Parks Date: Tue, 22 Sep 2009 11:11:45 +0000 Subject: Merging render-pipeline-6-qa-2 into viewer-2 Self reviewed. --- indra/llui/llfloater.cpp | 22 +++++++++++++--------- indra/llui/llmenugl.cpp | 8 ++++++++ indra/llui/lltabcontainer.cpp | 9 ++++++--- indra/llui/llui.cpp | 17 ++++++++++++++++- indra/llui/llui.h | 4 ++++ indra/llui/llview.cpp | 27 ++++++++++++++++++++++++++- indra/llui/llview.h | 1 + 7 files changed, 74 insertions(+), 14 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 228e23b67e..81915731c3 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -602,6 +602,8 @@ void LLFloater::openFloater(const LLSD& key) mOpenSignal(this, key); onOpen(key); + + dirtyRect(); } void LLFloater::closeFloater(bool app_quitting) @@ -667,7 +669,9 @@ void LLFloater::closeFloater(bool app_quitting) } } } - + + dirtyRect(); + // Close callback mCloseSignal(this, LLSD(app_quitting)); @@ -1933,8 +1937,8 @@ void LLFloaterView::restoreAll() LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLFloater* neighbor ) { LLRect base_rect = reference_floater->getRect(); - S32 width = neighbor->getRect().getWidth(); - S32 height = neighbor->getRect().getHeight(); + LLRect::tCoordType width = neighbor->getRect().getWidth(); + LLRect::tCoordType height = neighbor->getRect().getHeight(); LLRect new_rect = neighbor->getRect(); LLRect expanded_base_rect = base_rect; @@ -1953,10 +1957,10 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF } } - S32 left_margin = llmax(0, base_rect.mLeft); - S32 right_margin = llmax(0, getRect().getWidth() - base_rect.mRight); - S32 top_margin = llmax(0, getRect().getHeight() - base_rect.mTop); - S32 bottom_margin = llmax(0, base_rect.mBottom); + LLRect::tCoordType left_margin = llmax(0, base_rect.mLeft); + LLRect::tCoordType right_margin = llmax(0, getRect().getWidth() - base_rect.mRight); + LLRect::tCoordType top_margin = llmax(0, getRect().getHeight() - base_rect.mTop); + LLRect::tCoordType bottom_margin = llmax(0, base_rect.mBottom); // find position for floater in following order // right->left->bottom->top @@ -2262,8 +2266,8 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out // floater is hosted elsewhere, so ignore return; } - S32 screen_width = getSnapRect().getWidth(); - S32 screen_height = getSnapRect().getHeight(); + LLRect::tCoordType screen_width = getSnapRect().getWidth(); + LLRect::tCoordType screen_height = getSnapRect().getHeight(); // convert to local coordinate frame LLRect snap_rect_local = getLocalSnapRect(); diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index e0bb6bd5d3..03374b856b 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -408,6 +408,12 @@ void LLMenuItemGL::onCommit( void ) { getMenu()->clearHoverItem(); } + + if (mHighlight != highlight) + { + dirtyRect(); + } + mHighlight = highlight; } @@ -1233,6 +1239,8 @@ void LLMenuItemBranchGL::openMenu() branch->translate( delta_x, delta_y ); branch->setVisible( TRUE ); branch->getParent()->sendChildToFront(branch); + + dirtyRect(); } } diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 720ca692f7..b6eed3ef18 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -329,10 +329,13 @@ void LLTabContainer::draw() } // Hide all the buttons - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + if (getTabsHidden()) { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( FALSE ); + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( FALSE ); + } } LLPanel::draw(); diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 950eaf2ea7..000e85f78c 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -81,7 +81,8 @@ std::list gUntranslated; /*static*/ LLWindow* LLUI::sWindow = NULL; /*static*/ LLHtmlHelp* LLUI::sHtmlHelp = NULL; /*static*/ LLView* LLUI::sRootView = NULL; - +/*static*/ BOOL LLUI::sDirty = FALSE; +/*static*/ LLRect LLUI::sDirtyRect; /*static*/ std::vector LLUI::sXUIPaths; /*static*/ LLFrameTimer LLUI::sMouseIdleTimer; @@ -1603,6 +1604,20 @@ void LLUI::cleanupClass() sImageProvider->cleanUp(); } +//static +void LLUI::dirtyRect(LLRect rect) +{ + if (!sDirty) + { + sDirtyRect = rect; + sDirty = TRUE; + } + else + { + sDirtyRect.unionWith(rect); + } +} + //static void LLUI::translate(F32 x, F32 y, F32 z) diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 33338f30f9..fddf8192ad 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -174,6 +174,10 @@ public: static void loadIdentity(); static void translate(F32 x, F32 y, F32 z = 0.0f); + static LLRect sDirtyRect; + static BOOL sDirty; + static void dirtyRect(LLRect rect); + // Return the ISO639 language name ("en", "ko", etc.) for the viewer UI. // http://www.loc.gov/standards/iso639-2/php/code_list.php static std::string getLanguage(); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 46510804f8..8d723877d6 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -143,6 +143,7 @@ LLView::LLView(const LLView::Params& p) LLView::~LLView() { + dirtyRect(); //llinfos << "Deleting view " << mName << ":" << (void*) this << llendl; // llassert(LLView::sIsDrawing == FALSE); @@ -602,6 +603,7 @@ void LLView::setVisible(BOOL visible) if (!getParent() || getParent()->isInVisibleChain()) { // tell all children of this view that the visibility may have changed + dirtyRect(); handleVisibilityChange( visible ); } updateBoundingRect(); @@ -1297,7 +1299,7 @@ void LLView::drawChildren() { // Only draw views that are within the root view localRectToScreen(viewp->getRect(),&screenRect); - if ( rootRect.overlaps(screenRect) ) + if ( rootRect.overlaps(screenRect) && LLUI::sDirtyRect.overlaps(screenRect)) { glMatrixMode(GL_MODELVIEW); LLUI::pushMatrix(); @@ -1316,6 +1318,21 @@ void LLView::drawChildren() gGL.getTexUnit(0)->disable(); } +void LLView::dirtyRect() +{ + LLView* child = getParent(); + LLView* parent = child ? child->getParent() : NULL; + LLView* cur = this; + while (child && parent && parent->getParent()) + { //find third to top-most view + cur = child; + child = parent; + parent = parent->getParent(); + } + + LLUI::dirtyRect(cur->calcScreenRect()); +} + //Draw a box for debugging. void LLView::drawDebugRect() { @@ -1529,6 +1546,8 @@ void LLView::updateBoundingRect() { if (isDead()) return; + LLRect cur_rect = mBoundingRect; + if (mUseBoundingRect) { mBoundingRect = calcBoundingRect(); @@ -1543,6 +1562,12 @@ void LLView::updateBoundingRect() { getParent()->updateBoundingRect(); } + + if (mBoundingRect != cur_rect) + { + dirtyRect(); + } + } LLRect LLView::calcScreenRect() const diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 1f7e5afaae..bf3b5d0614 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -519,6 +519,7 @@ public: virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual void handleReshape(const LLRect& rect, bool by_user); + virtual void dirtyRect(); virtual void notifyParent(const LLSD& info); virtual void notifyChildren(const LLSD& info); -- cgit v1.2.3 From 12762053e5aff372a9f8d473c71aa81e805bb474 Mon Sep 17 00:00:00 2001 From: Martin Reddy Date: Tue, 22 Sep 2009 18:00:16 +0000 Subject: EXT-944 EXT-1026: converted the LLUrlRegistry::findUrl() method to work on an LLWString instead of a std::string, so that we don't have to worry about character offsets for variable-length-encoded UTF-8 strings. This was causing crashes whenever we would try to show a textbox with a URL and foreign characters (> 1 byte chars). Damn, I suck! --- indra/llui/lltextbase.cpp | 2 +- indra/llui/lltextbox.cpp | 4 ++-- indra/llui/lltexteditor.cpp | 11 +++++---- indra/llui/llurlaction.cpp | 4 ++-- indra/llui/llurlentry.cpp | 44 ++++++++++++++++++------------------ indra/llui/llurlentry.h | 4 ++-- indra/llui/llurlregistry.cpp | 12 +++++----- indra/llui/llurlregistry.h | 3 ++- indra/llui/tests/llurlentry_test.cpp | 34 +++++++++++++++------------- 9 files changed, 61 insertions(+), 57 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index cb60b4fe36..325c7a8104 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -429,7 +429,7 @@ LLContextMenu *LLTextBase::createUrlContextMenu(const std::string &in_url) // work out the XUI menu file to use for this url LLUrlMatch match; std::string url = in_url; - if (! LLUrlRegistry::instance().findUrl(url, match)) + if (! LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match)) { return NULL; } diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 810626268f..3cde42d75c 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -297,7 +297,7 @@ 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)) { S32 start = match.getStart(); S32 end = match.getEnd() + 1; @@ -573,7 +573,7 @@ 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 diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 983777b747..f7680a0a2b 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -3525,7 +3525,7 @@ void LLTextEditor::appendStyledText(const std::string &new_text, S32 start=0,end=0; LLUrlMatch match; - std::string text = new_text; + LLWString text = utf8str_to_wstring(new_text); while ( LLUrlRegistry::instance().findUrl(text, match, boost::bind(&LLTextEditor::onUrlLabelUpdated, this, _1, _2)) ) { @@ -3549,8 +3549,8 @@ void LLTextEditor::appendStyledText(const std::string &new_text, { part = (S32)LLTextParser::MIDDLE; } - std::string subtext=text.substr(0,start); - appendHighlightedText(subtext,allow_undo, prepend_newline, part, style_params); + std::string subtext = wstring_to_utf8str(text.substr(0,start)); + appendHighlightedText(subtext, allow_undo, prepend_newline, part, style_params); prepend_newline = false; } @@ -3595,7 +3595,8 @@ void LLTextEditor::appendStyledText(const std::string &new_text, } } if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END; - if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, style_params); + if (end < (S32)text.length()) appendHighlightedText(wstring_to_utf8str(text), allow_undo, + prepend_newline, part, style_params); } else { @@ -4137,7 +4138,7 @@ void LLTextEditor::updateLinkSegments() LLUrlMatch match; LLStyleSP style = static_cast(segment->getStyle()); std::string url_label = getText().substr(segment->getStart(), segment->getEnd()-segment->getStart()); - if (LLUrlRegistry::instance().findUrl(url_label, match)) + if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url_label), match)) { LLStringUtil::trim(url_label); style->setLinkHREF(url_label); diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index 3b689b93c0..7721d0e502 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -112,7 +112,7 @@ void LLUrlAction::clickAction(std::string url) void LLUrlAction::teleportToLocation(std::string url) { LLUrlMatch match; - if (LLUrlRegistry::instance().findUrl(url, match)) + if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match)) { if (! match.getLocation().empty()) { @@ -129,7 +129,7 @@ void LLUrlAction::copyURLToClipboard(std::string url) void LLUrlAction::copyLabelToClipboard(std::string url) { LLUrlMatch match; - if (LLUrlRegistry::instance().findUrl(url, match)) + if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match)) { LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel())); } diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index c20212c375..e4bcc27428 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -148,8 +148,8 @@ void LLUrlEntryBase::callObservers(const std::string &id, const std::string &lab // LLUrlEntryHTTP::LLUrlEntryHTTP() { - mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_http.xml"; mTooltip = LLTrans::getString("TooltipHttpUrl"); //mIcon = "gear.tga"; @@ -166,8 +166,8 @@ std::string LLUrlEntryHTTP::getLabel(const std::string &url, const LLUrlLabelCal // LLUrlEntryHTTPLabel::LLUrlEntryHTTPLabel() { - mPattern = boost::regex("\\[https?://\\S+[ \t]+[^\\]]+\\]", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"\\[https?://\\S+[ \t]+[^\\]]+\\]", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_http.xml"; mTooltip = LLTrans::getString("TooltipHttpUrl"); } @@ -188,8 +188,8 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) LLUrlEntrySLURL::LLUrlEntrySLURL() { // see http://slurl.com/about.php for details on the SLURL format - mPattern = boost::regex("http://slurl.com/secondlife/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"http://slurl.com/secondlife/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slurl.xml"; mTooltip = LLTrans::getString("TooltipSLURL"); } @@ -260,8 +260,8 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const // LLUrlEntryAgent::LLUrlEntryAgent() { - mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/about", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"secondlife:///app/agent/[\\da-f-]+/about", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_agent.xml"; mTooltip = LLTrans::getString("TooltipAgentUrl"); } @@ -302,8 +302,8 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa // LLUrlEntryGroup::LLUrlEntryGroup() { - mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/about", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"secondlife:///app/group/[\\da-f-]+/about", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_group.xml"; mTooltip = LLTrans::getString("TooltipGroupUrl"); } @@ -344,8 +344,8 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa /// LLUrlEntryParcel::LLUrlEntryParcel() { - mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"secondlife:///app/parcel/[\\da-f-]+/about", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_parcel.xml"; mTooltip = LLTrans::getString("TooltipParcelUrl"); } @@ -360,8 +360,8 @@ std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelC // LLUrlEntryPlace::LLUrlEntryPlace() { - mPattern = boost::regex("secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slurl.xml"; mTooltip = LLTrans::getString("TooltipSLURL"); } @@ -416,8 +416,8 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const // LLUrlEntryTeleport::LLUrlEntryTeleport() { - mPattern = boost::regex("secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_teleport.xml"; mTooltip = LLTrans::getString("TooltipTeleportUrl"); } @@ -488,8 +488,8 @@ std::string LLUrlEntryTeleport::getLocation(const std::string &url) const /// LLUrlEntryObjectIM::LLUrlEntryObjectIM() { - mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\\??\\S*", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"secondlife:///app/objectim/[\\da-f-]+\\??\\S*", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_objectim.xml"; mTooltip = LLTrans::getString("TooltipObjectIMUrl"); } @@ -532,8 +532,8 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const // LLUrlEntrySL::LLUrlEntrySL() { - mPattern = boost::regex("secondlife://(\\w+)?(:\\d+)?/\\S+", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"secondlife://(\\w+)?(:\\d+)?/\\S+", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slapp.xml"; mTooltip = LLTrans::getString("TooltipSLAPP"); } @@ -549,8 +549,8 @@ std::string LLUrlEntrySL::getLabel(const std::string &url, const LLUrlLabelCallb // LLUrlEntrySLLabel::LLUrlEntrySLLabel() { - mPattern = boost::regex("\\[secondlife://\\S+[ \t]+[^\\]]+\\]", - boost::regex::perl|boost::regex::icase); + mPattern = boost::wregex(L"\\[secondlife://\\S+[ \t]+[^\\]]+\\]", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slapp.xml"; mTooltip = LLTrans::getString("TooltipSLAPP"); } diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 54053872df..36758566ed 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -68,7 +68,7 @@ public: virtual ~LLUrlEntryBase(); /// Return the regex pattern that matches this Url - boost::regex getPattern() const { return mPattern; } + boost::wregex getPattern() const { return mPattern; } /// Return the url from a string that matched the regex virtual std::string getUrl(const std::string &string); @@ -102,7 +102,7 @@ protected: LLUrlLabelSignal *signal; } LLUrlEntryObserver; - boost::regex mPattern; + boost::wregex mPattern; std::string mIcon; std::string mMenuName; std::string mTooltip; diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index f2d340deb7..2ea3c59e03 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -75,9 +75,9 @@ void LLUrlRegistry::registerUrl(LLUrlEntryBase *url) } } -static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &end) +static bool matchRegex(const wchar_t *text, boost::wregex regex, U32 &start, U32 &end) { - boost::cmatch result; + boost::wcmatch result; bool found; // regex_search can potentially throw an exception, so check for it @@ -107,7 +107,7 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en } // ignore a terminating ')' when Url contains no matching '(' // see DEV-19842 for details - else if (text[end] == ')' && std::string(text+start, end-start).find('(') == std::string::npos) + else if (text[end] == ')' && LLWString(text+start, end-start).find('(') == std::string::npos) { end--; } @@ -115,10 +115,10 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en return true; } -bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) +bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) { // avoid costly regexes if there is clearly no URL in the text - if (text.find("://") == std::string::npos) + if (text.find(L"://") == std::string::npos) { return false; } @@ -149,7 +149,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL if (match_entry) { // fill in the LLUrlMatch object and return it - std::string url = text.substr(match_start, match_end - match_start + 1); + std::string url = wstring_to_utf8str(text.substr(match_start, match_end - match_start + 1)); match.setValues(match_start, match_end, match_entry->getUrl(url), match_entry->getLabel(url, cb), diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 84b033036c..bf5257d630 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -37,6 +37,7 @@ #include "llurlentry.h" #include "llurlmatch.h" #include "llsingleton.h" +#include "llstring.h" #include #include @@ -74,7 +75,7 @@ public: /// get the next Url in an input string, starting at a given character offset /// your callback is invoked if the matched Url's label changes in the future - bool findUrl(const std::string &text, LLUrlMatch &match, + bool findUrl(const LLWString &text, LLUrlMatch &match, const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback); private: diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 1e7a0f7f2c..89a80f1e73 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -44,17 +44,19 @@ namespace namespace tut { - void testRegex(const std::string &testname, boost::regex regex, + void testRegex(const std::string &testname, boost::wregex regex, const char *text, const std::string &expected) { std::string url = ""; - boost::cmatch result; - bool found = boost::regex_search(text, result, regex); + boost::wcmatch result; + LLWString wtext = utf8str_to_wstring(text); + const wchar_t *wctext = wtext.c_str(); + bool found = boost::regex_search(wctext, result, regex); if (found) { - S32 start = static_cast(result[0].first - text); - S32 end = static_cast(result[0].second - text); - url = std::string(text+start, end-start); + S32 start = static_cast(result[0].first - wctext); + S32 end = static_cast(result[0].second - wctext); + url = wstring_to_utf8str(wtext.substr(start, end-start)); } ensure_equals(testname, url, expected); } @@ -66,7 +68,7 @@ namespace tut // test LLUrlEntryHTTP - standard http Urls // LLUrlEntryHTTP url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("no valid url", r, "htp://slurl.com/", @@ -145,7 +147,7 @@ namespace tut // test LLUrlEntryHTTPLabel - wiki-style http Urls with labels // LLUrlEntryHTTPLabel url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("invalid wiki url [1]", r, "[http://www.example.org]", @@ -187,7 +189,7 @@ namespace tut // test LLUrlEntrySLURL - second life URLs // LLUrlEntrySLURL url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("no valid slurl [1]", r, "htp://slurl.com/secondlife/Ahern/50/50/50/", @@ -259,7 +261,7 @@ namespace tut // test LLUrlEntryAgent - secondlife://app/agent Urls // LLUrlEntryAgent url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("Invalid Agent Url", r, "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about", @@ -285,7 +287,7 @@ namespace tut // test LLUrlEntryGroup - secondlife://app/group Urls // LLUrlEntryGroup url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("Invalid Group Url", r, "secondlife:///app/group/00005ff3-4044-c79f-XXXX-fb28ae0df991/about", @@ -311,7 +313,7 @@ namespace tut // test LLUrlEntryPlace - secondlife:// URLs // LLUrlEntryPlace url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("no valid slurl [1]", r, "secondlife://Ahern/FOO/50/", @@ -359,7 +361,7 @@ namespace tut // test LLUrlEntryParcel - secondlife://app/parcel Urls // LLUrlEntryParcel url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("Invalid Classified Url", r, "secondlife:///app/parcel/0000060e-4b39-e00b-XXXX-d98b1934e3a8/about", @@ -384,7 +386,7 @@ namespace tut // test LLUrlEntryTeleport - secondlife://app/teleport URLs // LLUrlEntryTeleport url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("no valid teleport [1]", r, "http://slurl.com/secondlife/Ahern/50/50/50/", @@ -460,7 +462,7 @@ namespace tut // test LLUrlEntrySL - general secondlife:// URLs // LLUrlEntrySL url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("no valid slapp [1]", r, "http:///app/", @@ -498,7 +500,7 @@ namespace tut // test LLUrlEntrySLLabel - general secondlife:// URLs with labels // LLUrlEntrySLLabel url; - boost::regex r = url.getPattern(); + boost::wregex r = url.getPattern(); testRegex("invalid wiki url [1]", r, "[secondlife:///app/]", -- cgit v1.2.3 From 8f0625548ffe8fa26393b5e8d236ea6136dced3f Mon Sep 17 00:00:00 2001 From: Adam Moss Date: Tue, 22 Sep 2009 21:43:00 +0000 Subject: a stab at fixing this test. --- indra/llui/tests/llurlentry_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 89a80f1e73..e7af64187c 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -50,7 +50,7 @@ namespace tut std::string url = ""; boost::wcmatch result; LLWString wtext = utf8str_to_wstring(text); - const wchar_t *wctext = wtext.c_str(); + const wchar_t *wctext = (const wchar_t *)(wtext.c_str()); bool found = boost::regex_search(wctext, result, regex); if (found) { -- cgit v1.2.3 From d65c7b0f90acfbc88e94000a92703aad7413139e Mon Sep 17 00:00:00 2001 From: Adam Moss Date: Tue, 22 Sep 2009 22:12:54 +0000 Subject: svn merge -c-134040 . back-out my last commit - it fixed the build test, but the build still fails; I'll leave it alone... --- indra/llui/tests/llurlentry_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index e7af64187c..89a80f1e73 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -50,7 +50,7 @@ namespace tut std::string url = ""; boost::wcmatch result; LLWString wtext = utf8str_to_wstring(text); - const wchar_t *wctext = (const wchar_t *)(wtext.c_str()); + const wchar_t *wctext = wtext.c_str(); bool found = boost::regex_search(wctext, result, regex); if (found) { -- cgit v1.2.3 From 47abd559082f6023dcdfadd2ec740195b1d07990 Mon Sep 17 00:00:00 2001 From: Martin Reddy Date: Wed, 23 Sep 2009 13:57:06 +0000 Subject: EXT-944 EXT-1026: reverting my previous fix for these crashes. This didn't work on Windows because wchar_t is 2 bytes on that platform, not 4 bytes (whereas llwchar is 4 bytes everywhere). Boost's regex methods need to work on wchar_t, but I believe that using a UTF-16 string would still be prone to crashing on Windows as UTF-16 is still a variable-length encoding. Besides, trying to compile a UTF-16 solution generates weird link errors. Instead, I'm going to fix this problem a different way. And I'm starting by reverting the previous attempt. Thanks Win32. --- indra/llui/lltextbase.cpp | 2 +- indra/llui/lltextbox.cpp | 4 ++-- indra/llui/lltexteditor.cpp | 11 ++++----- indra/llui/llurlaction.cpp | 4 ++-- indra/llui/llurlentry.cpp | 44 ++++++++++++++++++------------------ indra/llui/llurlentry.h | 4 ++-- indra/llui/llurlregistry.cpp | 12 +++++----- indra/llui/llurlregistry.h | 3 +-- indra/llui/tests/llurlentry_test.cpp | 34 +++++++++++++--------------- 9 files changed, 57 insertions(+), 61 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 325c7a8104..cb60b4fe36 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -429,7 +429,7 @@ LLContextMenu *LLTextBase::createUrlContextMenu(const std::string &in_url) // work out the XUI menu file to use for this url LLUrlMatch match; std::string url = in_url; - if (! LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match)) + if (! LLUrlRegistry::instance().findUrl(url, match)) { return NULL; } diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 3cde42d75c..810626268f 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -297,7 +297,7 @@ LLWString LLTextBox::getWrappedText(const LLStringExplicit& in_text, F32 max_wid // find the next Url in the text string LLUrlMatch match; - while ( LLUrlRegistry::instance().findUrl(wtext, match)) + while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(wtext), match)) { S32 start = match.getStart(); S32 end = match.getEnd() + 1; @@ -573,7 +573,7 @@ void LLTextBox::updateDisplayTextAndSegments() LLWString text = mText.getWString(); // find the next Url in the text string - while ( LLUrlRegistry::instance().findUrl(text, match, + while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(text), match, boost::bind(&LLTextBox::onUrlLabelUpdated, this, _1, _2)) ) { // work out the char offset for the start/end of the url diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index f7680a0a2b..983777b747 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -3525,7 +3525,7 @@ void LLTextEditor::appendStyledText(const std::string &new_text, S32 start=0,end=0; LLUrlMatch match; - LLWString text = utf8str_to_wstring(new_text); + std::string text = new_text; while ( LLUrlRegistry::instance().findUrl(text, match, boost::bind(&LLTextEditor::onUrlLabelUpdated, this, _1, _2)) ) { @@ -3549,8 +3549,8 @@ void LLTextEditor::appendStyledText(const std::string &new_text, { part = (S32)LLTextParser::MIDDLE; } - std::string subtext = wstring_to_utf8str(text.substr(0,start)); - appendHighlightedText(subtext, allow_undo, prepend_newline, part, style_params); + std::string subtext=text.substr(0,start); + appendHighlightedText(subtext,allow_undo, prepend_newline, part, style_params); prepend_newline = false; } @@ -3595,8 +3595,7 @@ void LLTextEditor::appendStyledText(const std::string &new_text, } } if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END; - if (end < (S32)text.length()) appendHighlightedText(wstring_to_utf8str(text), allow_undo, - prepend_newline, part, style_params); + if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, style_params); } else { @@ -4138,7 +4137,7 @@ void LLTextEditor::updateLinkSegments() LLUrlMatch match; LLStyleSP style = static_cast(segment->getStyle()); std::string url_label = getText().substr(segment->getStart(), segment->getEnd()-segment->getStart()); - if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url_label), match)) + if (LLUrlRegistry::instance().findUrl(url_label, match)) { LLStringUtil::trim(url_label); style->setLinkHREF(url_label); diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index 7721d0e502..3b689b93c0 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -112,7 +112,7 @@ void LLUrlAction::clickAction(std::string url) void LLUrlAction::teleportToLocation(std::string url) { LLUrlMatch match; - if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match)) + if (LLUrlRegistry::instance().findUrl(url, match)) { if (! match.getLocation().empty()) { @@ -129,7 +129,7 @@ void LLUrlAction::copyURLToClipboard(std::string url) void LLUrlAction::copyLabelToClipboard(std::string url) { LLUrlMatch match; - if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match)) + if (LLUrlRegistry::instance().findUrl(url, match)) { LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel())); } diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index e4bcc27428..c20212c375 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -148,8 +148,8 @@ void LLUrlEntryBase::callObservers(const std::string &id, const std::string &lab // LLUrlEntryHTTP::LLUrlEntryHTTP() { - mPattern = boost::wregex(L"https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_http.xml"; mTooltip = LLTrans::getString("TooltipHttpUrl"); //mIcon = "gear.tga"; @@ -166,8 +166,8 @@ std::string LLUrlEntryHTTP::getLabel(const std::string &url, const LLUrlLabelCal // LLUrlEntryHTTPLabel::LLUrlEntryHTTPLabel() { - mPattern = boost::wregex(L"\\[https?://\\S+[ \t]+[^\\]]+\\]", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("\\[https?://\\S+[ \t]+[^\\]]+\\]", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_http.xml"; mTooltip = LLTrans::getString("TooltipHttpUrl"); } @@ -188,8 +188,8 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) LLUrlEntrySLURL::LLUrlEntrySLURL() { // see http://slurl.com/about.php for details on the SLURL format - mPattern = boost::wregex(L"http://slurl.com/secondlife/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("http://slurl.com/secondlife/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slurl.xml"; mTooltip = LLTrans::getString("TooltipSLURL"); } @@ -260,8 +260,8 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const // LLUrlEntryAgent::LLUrlEntryAgent() { - mPattern = boost::wregex(L"secondlife:///app/agent/[\\da-f-]+/about", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/about", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_agent.xml"; mTooltip = LLTrans::getString("TooltipAgentUrl"); } @@ -302,8 +302,8 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa // LLUrlEntryGroup::LLUrlEntryGroup() { - mPattern = boost::wregex(L"secondlife:///app/group/[\\da-f-]+/about", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/about", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_group.xml"; mTooltip = LLTrans::getString("TooltipGroupUrl"); } @@ -344,8 +344,8 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa /// LLUrlEntryParcel::LLUrlEntryParcel() { - mPattern = boost::wregex(L"secondlife:///app/parcel/[\\da-f-]+/about", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_parcel.xml"; mTooltip = LLTrans::getString("TooltipParcelUrl"); } @@ -360,8 +360,8 @@ std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelC // LLUrlEntryPlace::LLUrlEntryPlace() { - mPattern = boost::wregex(L"secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slurl.xml"; mTooltip = LLTrans::getString("TooltipSLURL"); } @@ -416,8 +416,8 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const // LLUrlEntryTeleport::LLUrlEntryTeleport() { - mPattern = boost::wregex(L"secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_teleport.xml"; mTooltip = LLTrans::getString("TooltipTeleportUrl"); } @@ -488,8 +488,8 @@ std::string LLUrlEntryTeleport::getLocation(const std::string &url) const /// LLUrlEntryObjectIM::LLUrlEntryObjectIM() { - mPattern = boost::wregex(L"secondlife:///app/objectim/[\\da-f-]+\\??\\S*", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\\??\\S*", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_objectim.xml"; mTooltip = LLTrans::getString("TooltipObjectIMUrl"); } @@ -532,8 +532,8 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const // LLUrlEntrySL::LLUrlEntrySL() { - mPattern = boost::wregex(L"secondlife://(\\w+)?(:\\d+)?/\\S+", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("secondlife://(\\w+)?(:\\d+)?/\\S+", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slapp.xml"; mTooltip = LLTrans::getString("TooltipSLAPP"); } @@ -549,8 +549,8 @@ std::string LLUrlEntrySL::getLabel(const std::string &url, const LLUrlLabelCallb // LLUrlEntrySLLabel::LLUrlEntrySLLabel() { - mPattern = boost::wregex(L"\\[secondlife://\\S+[ \t]+[^\\]]+\\]", - boost::regex::perl|boost::regex::icase); + mPattern = boost::regex("\\[secondlife://\\S+[ \t]+[^\\]]+\\]", + boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slapp.xml"; mTooltip = LLTrans::getString("TooltipSLAPP"); } diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 36758566ed..54053872df 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -68,7 +68,7 @@ public: virtual ~LLUrlEntryBase(); /// Return the regex pattern that matches this Url - boost::wregex getPattern() const { return mPattern; } + boost::regex getPattern() const { return mPattern; } /// Return the url from a string that matched the regex virtual std::string getUrl(const std::string &string); @@ -102,7 +102,7 @@ protected: LLUrlLabelSignal *signal; } LLUrlEntryObserver; - boost::wregex mPattern; + boost::regex mPattern; std::string mIcon; std::string mMenuName; std::string mTooltip; diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 2ea3c59e03..f2d340deb7 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -75,9 +75,9 @@ void LLUrlRegistry::registerUrl(LLUrlEntryBase *url) } } -static bool matchRegex(const wchar_t *text, boost::wregex regex, U32 &start, U32 &end) +static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &end) { - boost::wcmatch result; + boost::cmatch result; bool found; // regex_search can potentially throw an exception, so check for it @@ -107,7 +107,7 @@ static bool matchRegex(const wchar_t *text, boost::wregex regex, U32 &start, U32 } // ignore a terminating ')' when Url contains no matching '(' // see DEV-19842 for details - else if (text[end] == ')' && LLWString(text+start, end-start).find('(') == std::string::npos) + else if (text[end] == ')' && std::string(text+start, end-start).find('(') == std::string::npos) { end--; } @@ -115,10 +115,10 @@ static bool matchRegex(const wchar_t *text, boost::wregex regex, U32 &start, U32 return true; } -bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) +bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) { // avoid costly regexes if there is clearly no URL in the text - if (text.find(L"://") == std::string::npos) + if (text.find("://") == std::string::npos) { return false; } @@ -149,7 +149,7 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr if (match_entry) { // fill in the LLUrlMatch object and return it - std::string url = wstring_to_utf8str(text.substr(match_start, match_end - match_start + 1)); + std::string url = text.substr(match_start, match_end - match_start + 1); match.setValues(match_start, match_end, match_entry->getUrl(url), match_entry->getLabel(url, cb), diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index bf5257d630..84b033036c 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -37,7 +37,6 @@ #include "llurlentry.h" #include "llurlmatch.h" #include "llsingleton.h" -#include "llstring.h" #include #include @@ -75,7 +74,7 @@ public: /// get the next Url in an input string, starting at a given character offset /// your callback is invoked if the matched Url's label changes in the future - bool findUrl(const LLWString &text, LLUrlMatch &match, + bool findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback); private: diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 89a80f1e73..1e7a0f7f2c 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -44,19 +44,17 @@ namespace namespace tut { - void testRegex(const std::string &testname, boost::wregex regex, + void testRegex(const std::string &testname, boost::regex regex, const char *text, const std::string &expected) { std::string url = ""; - boost::wcmatch result; - LLWString wtext = utf8str_to_wstring(text); - const wchar_t *wctext = wtext.c_str(); - bool found = boost::regex_search(wctext, result, regex); + boost::cmatch result; + bool found = boost::regex_search(text, result, regex); if (found) { - S32 start = static_cast(result[0].first - wctext); - S32 end = static_cast(result[0].second - wctext); - url = wstring_to_utf8str(wtext.substr(start, end-start)); + S32 start = static_cast(result[0].first - text); + S32 end = static_cast(result[0].second - text); + url = std::string(text+start, end-start); } ensure_equals(testname, url, expected); } @@ -68,7 +66,7 @@ namespace tut // test LLUrlEntryHTTP - standard http Urls // LLUrlEntryHTTP url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("no valid url", r, "htp://slurl.com/", @@ -147,7 +145,7 @@ namespace tut // test LLUrlEntryHTTPLabel - wiki-style http Urls with labels // LLUrlEntryHTTPLabel url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("invalid wiki url [1]", r, "[http://www.example.org]", @@ -189,7 +187,7 @@ namespace tut // test LLUrlEntrySLURL - second life URLs // LLUrlEntrySLURL url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("no valid slurl [1]", r, "htp://slurl.com/secondlife/Ahern/50/50/50/", @@ -261,7 +259,7 @@ namespace tut // test LLUrlEntryAgent - secondlife://app/agent Urls // LLUrlEntryAgent url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("Invalid Agent Url", r, "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about", @@ -287,7 +285,7 @@ namespace tut // test LLUrlEntryGroup - secondlife://app/group Urls // LLUrlEntryGroup url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("Invalid Group Url", r, "secondlife:///app/group/00005ff3-4044-c79f-XXXX-fb28ae0df991/about", @@ -313,7 +311,7 @@ namespace tut // test LLUrlEntryPlace - secondlife:// URLs // LLUrlEntryPlace url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("no valid slurl [1]", r, "secondlife://Ahern/FOO/50/", @@ -361,7 +359,7 @@ namespace tut // test LLUrlEntryParcel - secondlife://app/parcel Urls // LLUrlEntryParcel url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("Invalid Classified Url", r, "secondlife:///app/parcel/0000060e-4b39-e00b-XXXX-d98b1934e3a8/about", @@ -386,7 +384,7 @@ namespace tut // test LLUrlEntryTeleport - secondlife://app/teleport URLs // LLUrlEntryTeleport url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("no valid teleport [1]", r, "http://slurl.com/secondlife/Ahern/50/50/50/", @@ -462,7 +460,7 @@ namespace tut // test LLUrlEntrySL - general secondlife:// URLs // LLUrlEntrySL url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("no valid slapp [1]", r, "http:///app/", @@ -500,7 +498,7 @@ namespace tut // test LLUrlEntrySLLabel - general secondlife:// URLs with labels // LLUrlEntrySLLabel url; - boost::wregex r = url.getPattern(); + boost::regex r = url.getPattern(); testRegex("invalid wiki url [1]", r, "[secondlife:///app/]", -- cgit v1.2.3 From a0e44e3dd3e09d24ac2d329aa87f4bd34a59f301 Mon Sep 17 00:00:00 2001 From: Martin Reddy Date: Wed, 23 Sep 2009 14:56:02 +0000 Subject: EXT-944 EXT-1026: re-fixing these crashing bugs by making sure that we don't use character offsets when mixing utf8 and wide strings. Internal JIRAs: DEV-40127 DEV-39966. --- indra/llui/lltextbox.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 810626268f..9de474a4f5 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -299,8 +299,9 @@ LLWString LLTextBox::getWrappedText(const LLStringExplicit& in_text, F32 max_wid LLUrlMatch match; while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(wtext), match)) { - S32 start = match.getStart(); - S32 end = match.getEnd() + 1; + LLWString wurl = utf8str_to_wstring(match.getUrl()); + S32 start = wtext.find(wurl); + S32 end = start + wurl.size(); // perform word wrap on the text before the Url final_wtext += wrapText(wtext.substr(0, start), hoffset, line_num, max_width); @@ -577,13 +578,17 @@ void LLTextBox::updateDisplayTextAndSegments() 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 seg_start = mDisplayText.size(); - S32 start = seg_start + match.getStart(); - end = start + match.getLabel().size(); + S32 start = seg_start + url_start; + S32 end = start + match.getLabel().size(); // create a segment for the text before the Url mSegments.insert(new LLNormalTextSegment(new LLStyle(), seg_start, start, *this)); - mDisplayText += text.substr(0, match.getStart()); + mDisplayText += text.substr(0, url_start); // create a segment for the Url text LLStyleSP html(new LLStyle); @@ -599,7 +604,7 @@ void LLTextBox::updateDisplayTextAndSegments() mDisplayText += utf8str_to_wstring(match.getLabel()); // move on to the rest of the text after the Url - text = text.substr(match.getEnd()+1, text.size() - match.getEnd()); + text = text.substr(url_end+1, text.size() - url_end); } // output a segment for the remaining text -- cgit v1.2.3 From 01c7b50edbca7d397dfe5e4ba3d8b5a2e4b6780d Mon Sep 17 00:00:00 2001 From: James Cook Date: Wed, 23 Sep 2009 18:45:51 +0000 Subject: EXT-646 Pinned menus display incorrectly. Menu needs to follow bottom-left corner to avoid being pulled up when floater resizes to accommodate. Fixed floater height computation, removed magic numbers. Added XML configuration file for menu_item_tear_off so we can set colors to make the lines visible when highlighted. Reviewed with Richard. --- indra/llui/llmenugl.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 03374b856b..75b0803890 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -121,6 +121,8 @@ const F32 ACTIVATE_HIGHLIGHT_TIME = 0.3f; static MenuRegistry::Register register_separator("menu_item_separator"); static MenuRegistry::Register register_menu_item_call("menu_item_call"); static MenuRegistry::Register register_menu_item_check("menu_item_check"); +// Created programmatically but we need to specify custom colors in xml +static MenuRegistry::Register register_menu_item_tear_off("menu_item_tear_off"); static MenuRegistry::Register register_menu("menu"); static LLDefaultChildRegistry::Register register_menu_default("menu"); @@ -390,8 +392,10 @@ void LLMenuItemGL::buildDrawLabel( void ) void LLMenuItemGL::onCommit( void ) { - // close all open menus by default - // if parent menu is actually visible (and we are not triggering menu item via accelerator) + // Check torn-off status to allow left-arrow keyboard navigation back + // to parent menu. + // Also, don't hide if item triggered by keyboard shortcut (and hence + // parent not visible). if (!getMenu()->getTornOff() && getMenu()->getVisible()) { @@ -3484,16 +3488,19 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : LLRect rect; menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView); // make sure this floater is big enough for menu - mTargetHeight = (F32)(rect.getHeight() + floater_header_size + 5); + mTargetHeight = (F32)(rect.getHeight() + floater_header_size); reshape(rect.getWidth(), rect.getHeight()); setRect(rect); // attach menu to floater - menup->setFollowsAll(); + menup->setFollows( FOLLOWS_LEFT | FOLLOWS_BOTTOM ); mOldParent = menup->getParent(); addChild(menup); menup->setVisible(TRUE); - menup->translate(-menup->getRect().mLeft + 1, -menup->getRect().mBottom + 1); + LLRect menu_rect = menup->getRect(); + menu_rect.setOriginAndSize( 1, 1, + menu_rect.getWidth(), menu_rect.getHeight()); + menup->setRect(menu_rect); menup->setDropShadowed(FALSE); mMenu = menup; @@ -3521,12 +3528,6 @@ void LLTearOffMenu::draw() // animate towards target height reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); } - else - { - // when in stasis, remain big enough to hold menu contents - mTargetHeight = (F32)(mMenu->getRect().getHeight() + floater_header_size + 4); - reshape(mMenu->getRect().getWidth() + 3, mMenu->getRect().getHeight() + floater_header_size + 5); - } LLFloater::draw(); } -- cgit v1.2.3 From afcdda2e361855e2a02eb39c8cec080019ac769f Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Wed, 23 Sep 2009 22:25:18 +0000 Subject: EXT-904 Build tools does not show tooltips on any checkbox EXT-877 There is no tooltip with a date for Time indicator in Nav bar EXT-860 Crosshairs and "Press ESC to..." warning are dislocated in mouselook mode when UI Size is not exactly set to 1.00 (Menu Me -> Preferences-> Graphics) EXT-783 Script editor inserts text twice when using the editors paste, or choosing LSL elements from the pull-down list. EXT-764 mis-location of cursor in edit script panel (fixed cursor width) EXT-658 Inventory window's "Fetched Items" needs spacing reviewed by James --- indra/llui/lltextbase.cpp | 3 ++- indra/llui/lltextbox.cpp | 7 ++++++- indra/llui/lltexteditor.cpp | 17 ++++++----------- indra/llui/llview.cpp | 27 +++++++++++++++++++-------- 4 files changed, 33 insertions(+), 21 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index cb60b4fe36..0fd6a14187 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -420,8 +420,9 @@ BOOL LLTextBase::handleToolTipForUrl(LLView *view, S32 x, S32 y, std::string& ms LLToolTipMgr::instance().show(LLToolTipParams() .message(tooltip_msg) .sticky_rect(sticky_rect_screen)); + return TRUE; } - return TRUE; + return FALSE; } LLContextMenu *LLTextBase::createUrlContextMenu(const std::string &in_url) diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 9de474a4f5..d6ae9e063e 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -161,7 +161,12 @@ BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask) BOOL LLTextBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen) { - return handleToolTipForUrl(this, x, y, msg, sticky_rect_screen); + if (handleToolTipForUrl(this, x, y, msg, sticky_rect_screen)) + { + return TRUE; + } + + return LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen); } void LLTextBox::setText(const LLStringExplicit& text) diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 983777b747..8d5f277b59 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1120,21 +1120,12 @@ void LLTextEditor::updateCursorXPos() } // constraint cursor to editable segments of document +// NOTE: index must be within document range S32 LLTextEditor::getEditableIndex(S32 index, bool increasing_direction) { - //// always allow editable position at end of doc - //if (index == getLength()) - //{ - // return index; - //} - segment_set_t::iterator segment_iter; S32 offset; getSegmentAndOffset(index, &segment_iter, &offset); - if (segment_iter == mSegments.end()) - { - return 0; - } LLTextSegmentPtr segmentp = *segment_iter; @@ -3194,7 +3185,11 @@ void LLTextEditor::draw() drawLineNumbers(); { - LLLocalClipRect clip(mTextRect); + // pad clipping rectangle so that cursor can draw at full width + // when at left edge of mTextRect + LLRect clip_rect(mTextRect); + clip_rect.stretch(1); + LLLocalClipRect clip(clip_rect); drawSelectionBackground(); drawPreeditMarker(); drawText(); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 8d723877d6..256c776293 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -675,9 +675,13 @@ LLView* LLView::childrenHandleToolTip(S32 x, S32 y, std::string& msg, LLRect& st LLView* viewp = *child_it; S32 local_x = x - viewp->getRect().mLeft; S32 local_y = y - viewp->getRect().mBottom; - if(viewp->pointInView(local_x, local_y) && - viewp->getVisible() && - viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen) ) + if(!viewp->pointInView(local_x, local_y) || + !viewp->getVisible()) + { + continue; + } + + if(viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen) ) { if (sDebugMouseHandling) { @@ -687,17 +691,22 @@ LLView* LLView::childrenHandleToolTip(S32 x, S32 y, std::string& msg, LLRect& st handled_view = viewp; break; } + + if( viewp->blockMouseEvent(x, y) ) + { + handled_view = viewp; + } } return handled_view; } BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen) { - LLView* child_handler = childrenHandleToolTip(x, y, msg, sticky_rect_screen); - BOOL handled = child_handler != NULL; + BOOL handled = FALSE; - // child widgets get priority on tooltips - if (!handled && !mToolTipMsg.empty()) + // parents provide tooltips first, which are optionally + // overridden by children + if (!mToolTipMsg.empty()) { // allow "scrubbing" over ui by showing next tooltip immediately // if previous one was still visible @@ -712,7 +721,9 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_s handled = TRUE; } - if( blockMouseEvent(x, y) ) + // child tooltips will override our own + LLView* child_handler = childrenHandleToolTip(x, y, msg, sticky_rect_screen); + if (child_handler) { handled = TRUE; } -- cgit v1.2.3 From f5b66f353e0a958a1fa4b17a40d4014ba4f046c9 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Thu, 24 Sep 2009 01:41:21 +0000 Subject: EXT-1008 - Unable to use the Tab key to select anything past Name Tags On removed bad LLUICtrl::onFocusLost and LLUICtrl::onFocusReceived overrides to be reviewed --- indra/llui/llradiogroup.cpp | 68 +++++++++++++++++++++++++-------------------- indra/llui/llradiogroup.h | 9 +++--- indra/llui/lluictrl.cpp | 50 --------------------------------- indra/llui/lluictrl.h | 3 -- 4 files changed, 43 insertions(+), 87 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index c66b9bde2b..d1ea5843eb 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -45,8 +45,6 @@ #include "lluictrlfactory.h" static LLDefaultChildRegistry::Register r1("radio_group"); - - static RadioGroupRegistry::Register register_radio_ctrl("radio_item"); @@ -83,6 +81,10 @@ LLRadioGroup::~LLRadioGroup() // virtual BOOL LLRadioGroup::postBuild() { + if (!mRadioButtons.empty()) + { + mRadioButtons[0]->setTabStop(true); + } if (mControlVariable) { setSelectedIndex(mControlVariable->getValue().asInteger()); @@ -102,7 +104,7 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled) child->setEnabled(enabled); if (index == mSelectedIndex && enabled == FALSE) { - setSelectedIndex(-1); + mSelectedIndex = -1; } break; } @@ -142,8 +144,28 @@ BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event) return FALSE; } + if (mSelectedIndex >= 0) + { + LLRadioCtrl* old_radio_item = mRadioButtons[mSelectedIndex]; + old_radio_item->setTabStop(false); + old_radio_item->setValue( FALSE ); + } + else + { + mRadioButtons[0]->setTabStop(false); + } + mSelectedIndex = index; + LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex]; + radio_item->setTabStop(true); + radio_item->setValue( TRUE ); + + if (hasFocus()) + { + mRadioButtons[mSelectedIndex]->focusFirstItem(FALSE, FALSE); + } + if (!from_event) { setControlValue(getSelectedIndex()); @@ -211,33 +233,6 @@ BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask) return handled; } -void LLRadioGroup::draw() -{ - S32 current_button = 0; - - BOOL take_focus = FALSE; - if (gFocusMgr.childHasKeyboardFocus(this)) - { - take_focus = TRUE; - } - - for (button_list_t::iterator iter = mRadioButtons.begin(); - iter != mRadioButtons.end(); ++iter) - { - LLRadioCtrl* radio = *iter; - BOOL selected = (current_button == mSelectedIndex); - radio->setValue( selected ); - if (take_focus && selected && !gFocusMgr.childHasKeyboardFocus(radio)) - { - // don't flash keyboard focus when navigating via keyboard - BOOL DONT_FLASH = FALSE; - radio->focusFirstItem(FALSE, DONT_FLASH); - } - current_button++; - } - - LLView::draw(); -} // When adding a child button, we need to ensure that the radio // group gets a message when the button is clicked. @@ -259,6 +254,19 @@ bool LLRadioGroup::addChild(LLView* view, S32 tab_group) return res; } +BOOL LLRadioGroup::handleMouseDown(S32 x, S32 y, MASK mask) +{ + // grab focus preemptively, before child button takes mousecapture + // + if (hasTabStop()) + { + focusFirstItem(FALSE, FALSE); + } + + return LLUICtrl::handleMouseDown(x, y, mask); +} + + // Handle one button being clicked. All child buttons must have this // function as their callback function. diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index b5516307fd..914548b6aa 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -54,7 +54,10 @@ public: Params() : length("length"), type("type") - {} + { + // radio items are not tabbable until they are selected + tab_stop = false; + } }; /*virtual*/ ~LLRadioCtrl(); @@ -103,6 +106,7 @@ public: virtual BOOL postBuild(); virtual bool addChild(LLView* view, S32 tab_group = 0); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask); @@ -117,9 +121,6 @@ public: virtual void setValue(const LLSD& value ); virtual LLSD getValue() const; - // Draw the group, but also fix the highlighting based on the control. - void draw(); - // Update the control as needed. Userdata must be a pointer to the button. void onClickButton(LLUICtrl* clicked_radio); diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 28cdb1ac27..8807e26f6b 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -506,56 +506,6 @@ void LLUICtrl::setFocus(BOOL b) } } -void LLUICtrl::onFocusReceived() -{ - // trigger callbacks - LLFocusableElement::onFocusReceived(); - - // find first view in hierarchy above new focus that is a LLUICtrl - LLView* viewp = getParent(); - LLUICtrl* last_focus = dynamic_cast(gFocusMgr.getLastKeyboardFocus()); - - while (viewp && !viewp->isCtrl()) - { - viewp = viewp->getParent(); - } - - // and if it has newly gained focus, call onFocusReceived() - LLUICtrl* ctrlp = static_cast(viewp); - if (ctrlp && (!last_focus || !last_focus->hasAncestor(ctrlp))) - { - ctrlp->onFocusReceived(); - } -} - -void LLUICtrl::onFocusLost() -{ - // trigger callbacks - LLFocusableElement::onFocusLost(); - - // find first view in hierarchy above old focus that is a LLUICtrl - LLView* viewp = getParent(); - while (viewp && !viewp->isCtrl()) - { - viewp = viewp->getParent(); - } - - // and if it has just lost focus, call onFocusReceived() - LLUICtrl* ctrlp = static_cast(viewp); - // hasFocus() includes any descendants - if (ctrlp && !ctrlp->hasFocus()) - { - ctrlp->onFocusLost(); - } -} - -void LLUICtrl::onTopLost() -{ - // trigger callbacks - LLFocusableElement::onTopLost(); -} - - // virtual void LLUICtrl::setTabStop( BOOL b ) { diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 4030230684..3add9393ea 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -153,9 +153,6 @@ protected: public: // LLView interface /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); - /*virtual*/ void onFocusReceived(); - /*virtual*/ void onFocusLost(); - /*virtual*/ void onTopLost(); /*virtual*/ BOOL isCtrl() const; /*virtual*/ void setTentative(BOOL b); /*virtual*/ BOOL getTentative() const; -- cgit v1.2.3 From 7b2737e0e14f815e69da7114dda693cdaea2c341 Mon Sep 17 00:00:00 2001 From: Martin Reddy Date: Thu, 24 Sep 2009 10:41:08 +0000 Subject: EXT-944 EXT-1026: cleaning up my quick fix for these issues. I've now added an explicit LLUrlRegistry::findUrl() method for LLWStrings. This deals with correcting the start/end range for the url appropriately. Now the API can be used without worrying about utf8/utf32 character offset issues. Internal JIRAs: DEV-40127 DEV-39966. --- indra/llui/lltextbox.cpp | 15 +++++++-------- indra/llui/llurlregistry.cpp | 28 ++++++++++++++++++++++++++++ indra/llui/llurlregistry.h | 6 +++++- 3 files changed, 40 insertions(+), 9 deletions(-) (limited to 'indra/llui') 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 #include -#include /// 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; -- cgit v1.2.3 From b5724bc0e97328a1859fc52b444e0a2edec255dd Mon Sep 17 00:00:00 2001 From: Martin Reddy Date: Fri, 25 Sep 2009 16:51:25 +0000 Subject: SNOW-194 DEV-40415: pulling this snowglobe patch into viewer 2.0. This fixes all of the parentheses warnings in the code. Original patch was reviewed by merov (and others). --- indra/llui/llmenugl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 75b0803890..f2d147ac39 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -2346,8 +2346,8 @@ void LLMenuGL::createJumpKeys() { char jump_key = uppercase_word[i]; - if (LLStringOps::isDigit(jump_key) || LLStringOps::isUpper(jump_key) && - mJumpKeys.find(jump_key) == mJumpKeys.end()) + if (LLStringOps::isDigit(jump_key) || (LLStringOps::isUpper(jump_key) && + mJumpKeys.find(jump_key) == mJumpKeys.end())) { mJumpKeys.insert(std::pair(jump_key, (*item_it))); (*item_it)->setJumpKey(jump_key); -- cgit v1.2.3