summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rwxr-xr-xindra/llui/llfolderview.cpp8
-rwxr-xr-xindra/llui/llmenugl.cpp2
-rwxr-xr-xindra/llui/llscrolllistctrl.cpp1
-rwxr-xr-xindra/llui/llsliderctrl.cpp15
-rwxr-xr-xindra/llui/llsliderctrl.h5
-rwxr-xr-xindra/llui/llspellcheck.cpp19
-rwxr-xr-xindra/llui/lltextbase.cpp44
-rwxr-xr-xindra/llui/lltexteditor.cpp26
-rwxr-xr-xindra/llui/llurlentry.cpp191
-rwxr-xr-xindra/llui/llurlentry.h41
-rwxr-xr-xindra/llui/llurlmatch.cpp5
-rwxr-xr-xindra/llui/llurlmatch.h8
-rwxr-xr-xindra/llui/llurlregistry.cpp26
-rwxr-xr-xindra/llui/llurlregistry.h2
-rw-r--r--indra/llui/llviewereventrecorder.cpp2
-rwxr-xr-xindra/llui/tests/llurlmatch_test.cpp30
16 files changed, 361 insertions, 64 deletions
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 9f06ccc827..f60129e601 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1610,7 +1610,7 @@ void LLFolderView::update()
LLFolderViewFilter& filter_object = getFolderViewModel()->getFilter();
- if (filter_object.isModified() && filter_object.isNotDefault())
+ if (filter_object.isModified() && filter_object.isNotDefault() && mParentPanel.get()->getVisible())
{
mNeedsAutoSelect = TRUE;
}
@@ -1652,8 +1652,10 @@ void LLFolderView::update()
scrollToShowSelection();
}
- BOOL filter_finished = getViewModelItem()->passedFilter()
- && mViewModel->contentsReady();
+ BOOL filter_finished = mViewModel->contentsReady()
+ && (getViewModelItem()->passedFilter()
+ || ( getViewModelItem()->getLastFilterGeneration() >= filter_object.getFirstSuccessGeneration()
+ && !filter_object.isModified()));
if (filter_finished
|| gFocusMgr.childHasKeyboardFocus(mParentPanel.get())
|| gFocusMgr.childHasMouseCapture(mParentPanel.get()))
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index f290edb5ff..7cdbcb0621 100755
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3689,7 +3689,7 @@ BOOL LLMenuHolderGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
handled = pMenu->handleKey(key, mask, TRUE);
}
- else
+ else if (mask == MASK_NONE || (key >= KEY_LEFT && key <= KEY_DOWN))
{
//highlight first enabled one
if(pMenu->highlightNextItem(NULL))
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 899a0bbab9..db8fdc46b7 100755
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1825,6 +1825,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
return TRUE;
}
}
+ return LLUICtrl::handleRightMouseDown(x, y, mask);
}
return FALSE;
}
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 127c97ecde..0056cb6dc4 100755
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -56,7 +56,8 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
mPrecision(p.decimal_digits),
mTextEnabledColor(p.text_color()),
mTextDisabledColor(p.text_disabled_color()),
- mLabelWidth(p.label_width)
+ mLabelWidth(p.label_width),
+ mEditorCommitSignal(NULL)
{
S32 top = getRect().getHeight();
S32 bottom = 0;
@@ -194,6 +195,11 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
updateText();
}
+LLSliderCtrl::~LLSliderCtrl()
+{
+ delete mEditorCommitSignal;
+}
+
// static
void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
@@ -306,6 +312,8 @@ void LLSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata )
if( success )
{
self->onCommit();
+ if (self->mEditorCommitSignal)
+ (*(self->mEditorCommitSignal))(self, self->getValueF32());
}
else
{
@@ -419,6 +427,11 @@ boost::signals2::connection LLSliderCtrl::setSliderMouseUpCallback( const commit
return mSlider->setMouseUpCallback( cb );
}
+boost::signals2::connection LLSliderCtrl::setSliderEditorCommitCallback( const commit_signal_t::slot_type& cb )
+{
+ if (!mEditorCommitSignal) mEditorCommitSignal = new commit_signal_t();
+ return mEditorCommitSignal->connect(cb);
+}
void LLSliderCtrl::onTabInto()
{
if( mEditor )
diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h
index 5153e33f49..67cca9ef04 100755
--- a/indra/llui/llsliderctrl.h
+++ b/indra/llui/llsliderctrl.h
@@ -81,7 +81,7 @@ protected:
LLSliderCtrl(const Params&);
friend class LLUICtrlFactory;
public:
- virtual ~LLSliderCtrl() {} // Children all cleaned up by default view destructor.
+ virtual ~LLSliderCtrl();
/*virtual*/ F32 getValueF32() const { return mSlider->getValueF32(); }
void setValue(F32 v, BOOL from_event = FALSE);
@@ -112,6 +112,7 @@ public:
boost::signals2::connection setSliderMouseDownCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setSliderMouseUpCallback( const commit_signal_t::slot_type& cb );
+ boost::signals2::connection setSliderEditorCommitCallback( const commit_signal_t::slot_type& cb );
/*virtual*/ void onTabInto();
@@ -150,6 +151,8 @@ private:
LLUIColor mTextEnabledColor;
LLUIColor mTextDisabledColor;
+
+ commit_signal_t* mEditorCommitSignal;
};
#endif // LL_LLSLIDERCTRL_H
diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp
index 250372da5b..0db4281059 100755
--- a/indra/llui/llspellcheck.cpp
+++ b/indra/llui/llspellcheck.cpp
@@ -144,12 +144,14 @@ void LLSpellChecker::refreshDictionaryMap()
const std::string user_path = getDictionaryUserPath();
// Load dictionary information (file name, friendly name, ...)
- llifstream user_file(user_path + DICT_FILE_MAIN, std::ios::binary);
+ std::string user_filename(user_path + DICT_FILE_MAIN);
+ llifstream user_file(user_filename.c_str(), std::ios::binary);
if ( (!user_file.is_open())
|| (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, user_file))
|| (0 == sDictMap.size()) )
{
- llifstream app_file(app_path + DICT_FILE_MAIN, std::ios::binary);
+ std::string app_filename(app_path + DICT_FILE_MAIN);
+ llifstream app_file(app_filename.c_str(), std::ios::binary);
if ( (!app_file.is_open())
|| (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, app_file))
|| (0 == sDictMap.size()) )
@@ -159,7 +161,7 @@ void LLSpellChecker::refreshDictionaryMap()
}
// Load user installed dictionary information
- llifstream custom_file(user_path + DICT_FILE_USER, std::ios::binary);
+ llifstream custom_file(user_filename.c_str(), std::ios::binary);
if (custom_file.is_open())
{
LLSD custom_dict_map;
@@ -215,7 +217,7 @@ void LLSpellChecker::addToDictFile(const std::string& dict_path, const std::stri
if (gDirUtilp->fileExists(dict_path))
{
- llifstream file_in(dict_path, std::ios::in);
+ llifstream file_in(dict_path.c_str(), std::ios::in);
if (file_in.is_open())
{
std::string word; int line_num = 0;
@@ -238,7 +240,7 @@ void LLSpellChecker::addToDictFile(const std::string& dict_path, const std::stri
word_list.push_back(word);
- llofstream file_out(dict_path, std::ios::out | std::ios::trunc);
+ llofstream file_out(dict_path.c_str(), std::ios::out | std::ios::trunc);
if (file_out.is_open())
{
file_out << word_list.size() << std::endl;
@@ -352,7 +354,7 @@ void LLSpellChecker::initHunspell(const std::string& dict_language)
if (gDirUtilp->fileExists(user_path + DICT_FILE_IGNORE))
{
- llifstream file_in(user_path + DICT_FILE_IGNORE, std::ios::in);
+ llifstream file_in((user_path + DICT_FILE_IGNORE).c_str(), std::ios::in);
if (file_in.is_open())
{
std::string word; int idxLine = 0;
@@ -463,7 +465,8 @@ void LLSpellChecker::removeDictionary(const std::string& dict_language)
LLSD LLSpellChecker::loadUserDictionaryMap()
{
LLSD dict_map;
- llifstream dict_file(getDictionaryUserPath() + DICT_FILE_USER, std::ios::binary);
+ std::string dict_filename(getDictionaryUserPath() + DICT_FILE_USER);
+ llifstream dict_file(dict_filename.c_str(), std::ios::binary);
if (dict_file.is_open())
{
LLSDSerialize::fromXMLDocument(dict_map, dict_file);
@@ -475,7 +478,7 @@ LLSD LLSpellChecker::loadUserDictionaryMap()
// static
void LLSpellChecker::saveUserDictionaryMap(const LLSD& dict_map)
{
- llofstream dict_file(getDictionaryUserPath() + DICT_FILE_USER, std::ios::trunc);
+ llofstream dict_file((getDictionaryUserPath() + DICT_FILE_USER).c_str(), std::ios::trunc);
if (dict_file.is_open())
{
LLSDSerialize::toPrettyXML(dict_map, dict_file);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 43e048d216..602a703450 100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -38,7 +38,6 @@
#include "lltextutil.h"
#include "lltooltip.h"
#include "lluictrl.h"
-#include "lluriparser.h"
#include "llurlaction.h"
#include "llurlregistry.h"
#include "llview.h"
@@ -2063,8 +2062,16 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
// output the styled Url
- //appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly());
appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.underlineOnHoverOnly());
+
+ // show query part of url with gray color only for LLUrlEntryHTTP and LLUrlEntryHTTPNoProtocol url entries
+ std::string label = match.getQuery();
+ if (label.size())
+ {
+ link_params.color = LLColor4::grey;
+ link_params.readonly_color = LLColor4::grey;
+ appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly());
+ }
// set the tooltip for the Url label
if (! match.getTooltip().empty())
@@ -2855,13 +2862,44 @@ void LLTextBase::updateRects()
needsReflow();
}
+ // update mTextBoundingRect after mVisibleTextRect took scrolls into account
+ if (!mLineInfoList.empty() && mScroller)
+ {
+ S32 delta_pos = 0;
+
+ switch(mVAlign)
+ {
+ case LLFontGL::TOP:
+ delta_pos = llmax(mVisibleTextRect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom);
+ break;
+ case LLFontGL::VCENTER:
+ delta_pos = (llmax(mVisibleTextRect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom) + (mVisibleTextRect.mBottom - mTextBoundingRect.mBottom)) / 2;
+ break;
+ case LLFontGL::BOTTOM:
+ delta_pos = mVisibleTextRect.mBottom - mTextBoundingRect.mBottom;
+ break;
+ case LLFontGL::BASELINE:
+ // do nothing
+ break;
+ }
+ // move line segments to fit new visible rect
+ if (delta_pos != 0)
+ {
+ for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
+ {
+ it->mRect.translate(0, delta_pos);
+ }
+ mTextBoundingRect.translate(0, delta_pos);
+ }
+ }
+
// update document container again, using new mVisibleTextRect (that has scrollbars enabled as needed)
doc_rect.mBottom = llmin(mVisibleTextRect.mBottom, mTextBoundingRect.mBottom);
doc_rect.mLeft = 0;
doc_rect.mRight = mScroller
? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight)
: mVisibleTextRect.getWidth();
- doc_rect.mTop = llmax(mVisibleTextRect.mTop, mTextBoundingRect.mTop);
+ doc_rect.mTop = llmax(mVisibleTextRect.getHeight(), mTextBoundingRect.getHeight()) + doc_rect.mBottom;
if (!mScroller)
{
// push doc rect to top of text widget
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index c433f8ccab..926326aaff 100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -814,7 +814,7 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
BOOL handled = FALSE;
// if I'm not currently selecting text
- if (!(hasSelection() && hasMouseCapture()))
+ if (!(mIsSelecting && hasMouseCapture()))
{
// let text segments handle mouse event
handled = LLTextBase::handleMouseUp(x, y, mask);
@@ -2448,12 +2448,30 @@ void LLTextEditor::updateLinkSegments()
LLTextSegment *segment = *it;
if (segment && segment->getStyle() && segment->getStyle()->isLink())
{
- // if the link's label (what the user can edit) is a valid Url,
- // then update the link's HREF to be the same as the label text.
- // This lets users edit Urls in-place.
LLStyleConstSP style = segment->getStyle();
LLStyleSP new_style(new LLStyle(*style));
LLWString url_label = wtext.substr(segment->getStart(), segment->getEnd()-segment->getStart());
+
+ segment_set_t::const_iterator next_it = mSegments.upper_bound(segment);
+ LLTextSegment *next_segment = *next_it;
+ if (next_segment)
+ {
+ LLWString next_url_label = wtext.substr(next_segment->getStart(), next_segment->getEnd()-next_segment->getStart());
+ std::string link_check = wstring_to_utf8str(url_label) + wstring_to_utf8str(next_url_label);
+ LLUrlMatch match;
+
+ if ( LLUrlRegistry::instance().findUrl(link_check, match))
+ {
+ if(match.getQuery() == wstring_to_utf8str(next_url_label))
+ {
+ continue;
+ }
+ }
+ }
+
+ // if the link's label (what the user can edit) is a valid Url,
+ // then update the link's HREF to be the same as the label text.
+ // This lets users edit Urls in-place.
if (LLUrlRegistry::instance().hasUrl(url_label))
{
std::string new_url = wstring_to_utf8str(url_label);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 7e4104c49b..5f60d80858 100755
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -39,8 +39,6 @@
#include "lluicolortable.h"
#include "message.h"
-#include "uriparser/Uri.h"
-
#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
// Utility functions
@@ -48,7 +46,8 @@ std::string localize_slapp_label(const std::string& url, const std::string& full
LLUrlEntryBase::LLUrlEntryBase()
-{}
+{
+}
LLUrlEntryBase::~LLUrlEntryBase()
{
@@ -187,6 +186,30 @@ bool LLUrlEntryBase::isWikiLinkCorrect(std::string url)
return (LLUrlRegistry::instance().hasUrl(label)) ? false : true;
}
+std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const
+{
+ LLUriParser up(unescapeUrl(url));
+ up.normalize();
+
+ std::string label;
+ up.extractParts();
+ up.glueFirst(label);
+
+ return label;
+}
+
+std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
+{
+ LLUriParser up(unescapeUrl(url));
+
+ std::string query;
+ up.extractParts();
+ up.glueSecond(query);
+
+ return query;
+}
+
+
static std::string getStringAfterToken(const std::string str, const std::string token)
{
size_t pos = str.find(token);
@@ -203,6 +226,7 @@ static std::string getStringAfterToken(const std::string str, const std::string
// LLUrlEntryHTTP Describes generic http: and https: Urls
//
LLUrlEntryHTTP::LLUrlEntryHTTP()
+ : LLUrlEntryBase()
{
mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
boost::regex::perl|boost::regex::icase);
@@ -212,6 +236,25 @@ LLUrlEntryHTTP::LLUrlEntryHTTP()
std::string LLUrlEntryHTTP::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
+ return urlToLabelWithGreyQuery(url);
+}
+
+std::string LLUrlEntryHTTP::getQuery(const std::string &url) const
+{
+ return urlToGreyQuery(url);
+}
+
+std::string LLUrlEntryHTTP::getUrl(const std::string &string) const
+{
+ if (string.find("://") == std::string::npos)
+ {
+ return "http://" + escapeUrl(string);
+ }
+ return escapeUrl(string);
+}
+
+std::string LLUrlEntryHTTP::getTooltip(const std::string &url) const
+{
return unescapeUrl(url);
}
@@ -247,6 +290,7 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) const
// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com
//
LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol()
+ : LLUrlEntryBase()
{
mPattern = boost::regex("("
"\\bwww\\.\\S+\\.\\S+" // i.e. www.FOO.BAR
@@ -260,7 +304,12 @@ LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol()
std::string LLUrlEntryHTTPNoProtocol::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
- return unescapeUrl(url);
+ return urlToLabelWithGreyQuery(url);
+}
+
+std::string LLUrlEntryHTTPNoProtocol::getQuery(const std::string &url) const
+{
+ return urlToGreyQuery(url);
}
std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) const
@@ -272,6 +321,95 @@ std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) const
return escapeUrl(string);
}
+std::string LLUrlEntryHTTPNoProtocol::getTooltip(const std::string &url) const
+{
+ return unescapeUrl(url);
+}
+
+LLUrlEntryInvalidSLURL::LLUrlEntryInvalidSLURL()
+ : LLUrlEntryBase()
+{
+ mPattern = boost::regex("(http://(maps.secondlife.com|slurl.com)/secondlife/|secondlife://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
+ boost::regex::perl|boost::regex::icase);
+ mMenuName = "menu_url_http.xml";
+ mTooltip = LLTrans::getString("TooltipHttpUrl");
+}
+
+std::string LLUrlEntryInvalidSLURL::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+
+ return escapeUrl(url);
+}
+
+std::string LLUrlEntryInvalidSLURL::getUrl(const std::string &string) const
+{
+ return escapeUrl(string);
+}
+
+std::string LLUrlEntryInvalidSLURL::getTooltip(const std::string &url) const
+{
+ return unescapeUrl(url);
+}
+
+bool LLUrlEntryInvalidSLURL::isSLURLvalid(const std::string &url) const
+{
+ S32 actual_parts;
+
+ if(url.find(".com/secondlife/") != std::string::npos)
+ {
+ actual_parts = 5;
+ }
+ else if(url.find("/app/") != std::string::npos)
+ {
+ actual_parts = 6;
+ }
+ else
+ {
+ actual_parts = 3;
+ }
+
+ LLURI uri(url);
+ LLSD path_array = uri.pathArray();
+ S32 path_parts = path_array.size();
+ S32 x,y,z;
+
+ if (path_parts == actual_parts)
+ {
+ // handle slurl with (X,Y,Z) coordinates
+ LLStringUtil::convertToS32(path_array[path_parts-3],x);
+ LLStringUtil::convertToS32(path_array[path_parts-2],y);
+ LLStringUtil::convertToS32(path_array[path_parts-1],z);
+
+ if((x>= 0 && x<= 256) && (y>= 0 && y<= 256) && (z>= 0))
+ {
+ return TRUE;
+ }
+ }
+ else if (path_parts == (actual_parts-1))
+ {
+ // handle slurl with (X,Y) coordinates
+
+ LLStringUtil::convertToS32(path_array[path_parts-2],x);
+ LLStringUtil::convertToS32(path_array[path_parts-1],y);
+ ;
+ if((x>= 0 && x<= 256) && (y>= 0 && y<= 256))
+ {
+ return TRUE;
+ }
+ }
+ else if (path_parts == (actual_parts-2))
+ {
+ // handle slurl with (X) coordinate
+ LLStringUtil::convertToS32(path_array[path_parts-1],x);
+ if(x>= 0 && x<= 256)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
//
// LLUrlEntrySLURL Describes generic http: and https: Urls
//
@@ -293,6 +431,7 @@ std::string LLUrlEntrySLURL::getLabel(const std::string &url, const LLUrlLabelCa
// - http://slurl.com/secondlife/Place/X
// - http://slurl.com/secondlife/Place
//
+
LLURI uri(url);
LLSD path_array = uri.pathArray();
S32 path_parts = path_array.size();
@@ -345,30 +484,56 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
}
//
-// LLUrlEntrySeconlifeURLs Describes *secondlife.com and *lindenlab.com urls to substitute icon 'hand.png' before link
+// LLUrlEntrySeconlifeURL Describes *secondlife.com/ and *lindenlab.com/ urls to substitute icon 'hand.png' before link
//
-LLUrlEntrySeconlifeURL::LLUrlEntrySeconlifeURL()
-{
- mPattern = boost::regex("\\b(https?://)?([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?(/\\S*)?\\b",
+LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
+{
+ mPattern = boost::regex("(https?://)?([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?\\/\\S*",
boost::regex::perl|boost::regex::icase);
mIcon = "Hand";
mMenuName = "menu_url_http.xml";
+ mTooltip = LLTrans::getString("TooltipHttpUrl");
}
-std::string LLUrlEntrySeconlifeURL::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+/// Return the url from a string that matched the regex
+std::string LLUrlEntrySecondlifeURL::getUrl(const std::string &string) const
{
- LLUriParser up(url);
- up.extractParts();
- return up.host();
+ if (string.find("://") == std::string::npos)
+ {
+ return "https://" + escapeUrl(string);
+ }
+ return escapeUrl(string);
}
-std::string LLUrlEntrySeconlifeURL::getTooltip(const std::string &url) const
+std::string LLUrlEntrySecondlifeURL::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+ return urlToLabelWithGreyQuery(url);
+}
+
+std::string LLUrlEntrySecondlifeURL::getQuery(const std::string &url) const
+{
+ return urlToGreyQuery(url);
+}
+
+std::string LLUrlEntrySecondlifeURL::getTooltip(const std::string &url) const
{
return url;
}
//
+// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com and *lindenlab.com urls to substitute icon 'hand.png' before link
+//
+LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()
+ {
+ mPattern = boost::regex("(https?://)?([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(?!\\S)",
+ boost::regex::perl|boost::regex::icase);
+
+ mIcon = "Hand";
+ mMenuName = "menu_url_http.xml";
+}
+
+//
// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 1cb11cdb1c..60a494974f 100755
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -78,6 +78,9 @@ public:
/// Given a matched Url, return a label for the Url
virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; }
+ /// Return port, query and fragment parts for the Url
+ virtual std::string getQuery(const std::string &url) const { return ""; }
+
/// Return an icon that can be displayed next to Urls of this type
virtual std::string getIcon(const std::string &url);
@@ -104,6 +107,8 @@ public:
bool isWikiLinkCorrect(std::string url);
+ virtual bool isSLURLvalid(const std::string &url) const { return TRUE; };
+
protected:
std::string getIDStringFromUrl(const std::string &url) const;
std::string escapeUrl(const std::string &url) const;
@@ -111,6 +116,8 @@ protected:
std::string getLabelFromWikiLink(const std::string &url) const;
std::string getUrlFromWikiLink(const std::string &string) const;
void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb);
+ std::string urlToLabelWithGreyQuery(const std::string &url) const;
+ std::string urlToGreyQuery(const std::string &url) const;
virtual void callObservers(const std::string &id, const std::string &label, const std::string& icon);
typedef struct {
@@ -133,6 +140,9 @@ class LLUrlEntryHTTP : public LLUrlEntryBase
public:
LLUrlEntryHTTP();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getQuery(const std::string &url) const;
+ /*virtual*/ std::string getUrl(const std::string &string) const;
+ /*virtual*/ std::string getTooltip(const std::string &url) const;
};
///
@@ -155,7 +165,20 @@ class LLUrlEntryHTTPNoProtocol : public LLUrlEntryBase
public:
LLUrlEntryHTTPNoProtocol();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getQuery(const std::string &url) const;
/*virtual*/ std::string getUrl(const std::string &string) const;
+ /*virtual*/ std::string getTooltip(const std::string &url) const;
+};
+
+class LLUrlEntryInvalidSLURL : public LLUrlEntryBase
+{
+public:
+ LLUrlEntryInvalidSLURL();
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getUrl(const std::string &string) const;
+ /*virtual*/ std::string getTooltip(const std::string &url) const;
+
+ bool isSLURLvalid(const std::string &url) const;
};
///
@@ -172,16 +195,24 @@ public:
///
/// LLUrlEntrySeconlifeURLs Describes *secondlife.com and *lindenlab.com Urls
///
-class LLUrlEntrySeconlifeURL : public LLUrlEntryBase
+class LLUrlEntrySecondlifeURL : public LLUrlEntryBase
{
public:
- LLUrlEntrySeconlifeURL();
- bool isTrusted() const { return true; }
+ LLUrlEntrySecondlifeURL();
+ /*virtual*/ bool isTrusted() const { return true; }
+ /*virtual*/ std::string getUrl(const std::string &string) const;
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getQuery(const std::string &url) const;
/*virtual*/ std::string getTooltip(const std::string &url) const;
+};
-private:
- std::string mLabel;
+///
+/// LLUrlEntrySeconlifeURLs Describes *secondlife.com and *lindenlab.com Urls
+///
+class LLUrlEntrySimpleSecondlifeURL : public LLUrlEntrySecondlifeURL
+{
+public:
+ LLUrlEntrySimpleSecondlifeURL();
};
///
diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp
index 016d1ca92d..2f2ac969e1 100755
--- a/indra/llui/llurlmatch.cpp
+++ b/indra/llui/llurlmatch.cpp
@@ -42,8 +42,8 @@ LLUrlMatch::LLUrlMatch() :
{
}
-void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
- const std::string &label, const std::string &tooltip,
+void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label,
+ const std::string& query, const std::string &tooltip,
const std::string &icon, const LLStyle::Params& style,
const std::string &menu, const std::string &location,
const LLUUID& id, bool underline_on_hover_only, bool trusted)
@@ -52,6 +52,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
mEnd = end;
mUrl = url;
mLabel = label;
+ mQuery = query;
mTooltip = tooltip;
mIcon = icon;
mStyle = style;
diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h
index 9f8960b32f..ff699902ca 100755
--- a/indra/llui/llurlmatch.h
+++ b/indra/llui/llurlmatch.h
@@ -62,6 +62,9 @@ public:
/// return a label that can be used for the display of this Url
std::string getLabel() const { return mLabel; }
+ /// return a right part of url which should be drawn in grey
+ std::string getQuery() const { return mQuery; }
+
/// return a message that could be displayed in a tooltip or status bar
std::string getTooltip() const { return mTooltip; }
@@ -85,10 +88,10 @@ public:
/// Change the contents of this match object (used by LLUrlRegistry)
void setValues(U32 start, U32 end, const std::string &url, const std::string &label,
- const std::string &tooltip, const std::string &icon,
+ const std::string& query, const std::string &tooltip, const std::string &icon,
const LLStyle::Params& style, const std::string &menu,
const std::string &location, const LLUUID& id,
- bool underline_on_hover_only = false, bool trusted = false );
+ bool underline_on_hover_only = false, bool trusted = false);
const LLUUID& getID() const { return mID; }
private:
@@ -96,6 +99,7 @@ private:
U32 mEnd;
std::string mUrl;
std::string mLabel;
+ std::string mQuery;
std::string mTooltip;
std::string mIcon;
std::string mMenuName;
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 9e8d8d01f1..1143574968 100755
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -44,10 +44,13 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryNoLink());
mUrlEntryIcon = new LLUrlEntryIcon();
registerUrl(mUrlEntryIcon);
+ mLLUrlEntryInvalidSLURL = new LLUrlEntryInvalidSLURL();
+ registerUrl(mLLUrlEntryInvalidSLURL);
registerUrl(new LLUrlEntrySLURL());
// decorated links for host names like: secondlife.com and lindenlab.com
- registerUrl(new LLUrlEntrySeconlifeURL());
+ registerUrl(new LLUrlEntrySecondlifeURL());
+ registerUrl(new LLUrlEntrySimpleSecondlifeURL());
registerUrl(new LLUrlEntryHTTP());
mUrlEntryHTTPLabel = new LLUrlEntryHTTPLabel();
@@ -188,6 +191,14 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
if (start < match_start || match_entry == NULL)
{
+ if (mLLUrlEntryInvalidSLURL == *it)
+ {
+ if(url_entry && url_entry->isSLURLvalid(text.substr(start, end - start + 1)))
+ {
+ continue;
+ }
+ }
+
if((mUrlEntryHTTPLabel == *it) || (mUrlEntrySLLabel == *it))
{
if(url_entry && !url_entry->isWikiLinkCorrect(text.substr(start, end - start + 1)))
@@ -209,13 +220,17 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
// fill in the LLUrlMatch object and return it
std::string url = text.substr(match_start, match_end - match_start + 1);
- LLUriParser up(url);
- up.normalize();
- url = up.normalizedUri();
+ if (match_entry == mUrlEntryTrusted)
+ {
+ LLUriParser up(url);
+ up.normalize();
+ url = up.normalizedUri();
+ }
match.setValues(match_start, match_end,
match_entry->getUrl(url),
match_entry->getLabel(url, cb),
+ match_entry->getQuery(url),
match_entry->getTooltip(url),
match_entry->getIcon(url),
match_entry->getStyle(),
@@ -243,7 +258,7 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
// 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);
+ size_t start = text.find(wurl);
if (start == std::string::npos)
{
return false;
@@ -252,6 +267,7 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
match.setValues(start, end, match.getUrl(),
match.getLabel(),
+ match.getQuery(),
match.getTooltip(),
match.getIcon(),
match.getStyle(),
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index 1cb403dfc9..5ce4048d5d 100755
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -93,7 +93,9 @@ private:
friend class LLSingleton<LLUrlRegistry>;
std::vector<LLUrlEntryBase *> mUrlEntry;
+ LLUrlEntryBase* mUrlEntryTrusted;
LLUrlEntryBase* mUrlEntryIcon;
+ LLUrlEntryBase* mLLUrlEntryInvalidSLURL;
LLUrlEntryBase* mUrlEntryHTTPLabel;
LLUrlEntryBase* mUrlEntrySLLabel;
};
diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp
index c5a4354f32..9fe6a542b4 100644
--- a/indra/llui/llviewereventrecorder.cpp
+++ b/indra/llui/llviewereventrecorder.cpp
@@ -50,7 +50,7 @@ bool LLViewerEventRecorder::displayViewerEventRecorderMenuItems() {
void LLViewerEventRecorder::setEventLoggingOn() {
if (! mLog.is_open()) {
- mLog.open(mLogFilename, llofstream::out);
+ mLog.open(mLogFilename.c_str(), std::ios_base::out);
}
logEvents=true;
LL_DEBUGS() << "LLViewerEventRecorder::setEventLoggingOn event logging turned on" << LL_ENDL;
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 55c1efefef..843886eb69 100755
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -151,7 +151,7 @@ namespace tut
LLUrlMatch match;
ensure("empty()", match.empty());
- match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(0, 1, "http://secondlife.com", "", "Second Life", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure("! empty()", ! match.empty());
}
@@ -164,7 +164,7 @@ namespace tut
LLUrlMatch match;
ensure_equals("getStart() == 0", match.getStart(), 0);
- match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getStart() == 10", match.getStart(), 10);
}
@@ -177,7 +177,7 @@ namespace tut
LLUrlMatch match;
ensure_equals("getEnd() == 0", match.getEnd(), 0);
- match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getEnd() == 20", match.getEnd(), 20);
}
@@ -190,10 +190,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getUrl() == ''", match.getUrl(), "");
- match.setValues(10, 20, "http://slurl.com/", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "http://slurl.com/", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/");
- match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getUrl() == '' (2)", match.getUrl(), "");
}
@@ -206,10 +206,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getLabel() == ''", match.getLabel(), "");
- match.setValues(10, 20, "", "Label", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "Label", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label");
- match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getLabel() == '' (2)", match.getLabel(), "");
}
@@ -222,10 +222,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getTooltip() == ''", match.getTooltip(), "");
- match.setValues(10, 20, "", "", "Info", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "Info", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info");
- match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getTooltip() == '' (2)", match.getTooltip(), "");
}
@@ -238,10 +238,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getIcon() == ''", match.getIcon(), "");
- match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "Icon", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon");
- match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure_equals("getIcon() == '' (2)", match.getIcon(), "");
}
@@ -254,10 +254,10 @@ namespace tut
LLUrlMatch match;
ensure("getMenuName() empty", match.getMenuName().empty());
- match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "", LLUUID::null);
ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml");
- match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure("getMenuName() empty (2)", match.getMenuName().empty());
}
@@ -270,10 +270,10 @@ namespace tut
LLUrlMatch match;
ensure("getLocation() empty", match.getLocation().empty());
- match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "Paris", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "Paris", LLUUID::null);
ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris");
- match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
+ match.setValues(10, 20, "", "", "", "", "", LLStyle::Params(), "", "", LLUUID::null);
ensure("getLocation() empty (2)", match.getLocation().empty());
}
}