diff options
author | Loren Shih <seraph@lindenlab.com> | 2010-02-02 17:15:46 -0500 |
---|---|---|
committer | Loren Shih <seraph@lindenlab.com> | 2010-02-02 17:15:46 -0500 |
commit | f22fc1e6129a7e56421a0777d69c64265d9ec4af (patch) | |
tree | 43dc78b1795ef407db7b9124472626fa77ae6621 | |
parent | 847a3a12208359653aa7432f7f64c31669ec8963 (diff) | |
parent | e3344abb95802646912f357d214538966f3f2357 (diff) |
automated merge viewer2.0->viewer2.0
69 files changed, 883 insertions, 333 deletions
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index de46d89d6f..a55915af35 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1650,24 +1650,8 @@ void LLFloater::draw() } else { - //FIXME: get rid of this hack - // draw children - LLView* focused_child = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus()); - BOOL focused_child_visible = FALSE; - if (focused_child && focused_child->getParent() == this) - { - focused_child_visible = focused_child->getVisible(); - focused_child->setVisible(FALSE); - } - // don't call LLPanel::draw() since we've implemented custom background rendering LLView::draw(); - - if (focused_child_visible) - { - focused_child->setVisible(TRUE); - } - drawChild(focused_child); } // update tearoff button for torn off floaters @@ -2579,6 +2563,8 @@ void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list) view->pushVisible(visible); } } + + LLFloaterReg::blockShowFloaters(true); } void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) @@ -2596,6 +2582,8 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) view->popVisible(); } } + + LLFloaterReg::blockShowFloaters(false); } void LLFloater::setInstanceName(const std::string& name) diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index eb67e3a561..5de3934c8a 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -34,6 +34,7 @@ #include "llfloaterreg.h" +//#include "llagent.h" #include "llfloater.h" #include "llmultifloater.h" #include "llfloaterreglistener.h" @@ -45,6 +46,7 @@ LLFloaterReg::instance_list_t LLFloaterReg::sNullInstanceList; LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap; LLFloaterReg::build_map_t LLFloaterReg::sBuildMap; std::map<std::string,std::string> LLFloaterReg::sGroupMap; +bool LLFloaterReg::sBlockShowFloaters = false; static LLFloaterRegListener sFloaterRegListener; @@ -217,6 +219,8 @@ LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(const std::str //static LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus) { + if( sBlockShowFloaters ) + return 0;// LLFloater* instance = getInstance(name, key); if (instance) { diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index 634a235926..8a11d5c3f2 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -75,6 +75,7 @@ private: static instance_map_t sInstanceMap; static build_map_t sBuildMap; static std::map<std::string,std::string> sGroupMap; + static bool sBlockShowFloaters; public: // Registration @@ -152,6 +153,8 @@ public: { return dynamic_cast<T*>(showInstance(name, key, focus)); } + + static void blockShowFloaters(bool value) { sBlockShowFloaters = value;} }; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index cb5aea272d..eb2b4f7705 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -70,7 +70,7 @@ const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing const F32 AUTO_SCROLL_TIME = 0.05f; const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval? -const std::string PASSWORD_ASTERISK( "\xE2\x97\x8F" ); // U+25CF BLACK CIRCLE +const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor"); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 259522a932..b977e50bc1 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1024,6 +1024,16 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c) } //virtual +void LLTextBase::handleVisibilityChange( BOOL new_visibility ) +{ + if(!new_visibility && mPopupMenu) + { + mPopupMenu->hide(); + } + LLUICtrl::handleVisibilityChange(new_visibility); +} + +//virtual void LLTextBase::setValue(const LLSD& value ) { setText(value.asString()); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index b5c7fab67a..ed2f239476 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -122,6 +122,7 @@ public: /*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; } /*virtual*/ void setColor( const LLColor4& c ); virtual void setReadOnlyColor(const LLColor4 &c); + virtual void handleVisibilityChange( BOOL new_visibility ); /*virtual*/ void setValue(const LLSD& value ); /*virtual*/ LLTextViewModel* getViewModel() const; diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 58148ad2aa..b20de914a0 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -49,7 +49,7 @@ LLUrlEntryBase::~LLUrlEntryBase() { } -std::string LLUrlEntryBase::getUrl(const std::string &string) +std::string LLUrlEntryBase::getUrl(const std::string &string) const { return escapeUrl(string); } @@ -89,7 +89,7 @@ std::string LLUrlEntryBase::escapeUrl(const std::string &url) const return LLURI::escape(url, no_escape_chars, true); } -std::string LLUrlEntryBase::getLabelFromWikiLink(const std::string &url) +std::string LLUrlEntryBase::getLabelFromWikiLink(const std::string &url) const { // return the label part from [http://www.example.org Label] const char *text = url.c_str(); @@ -105,7 +105,7 @@ std::string LLUrlEntryBase::getLabelFromWikiLink(const std::string &url) return unescapeUrl(url.substr(start, url.size()-start-1)); } -std::string LLUrlEntryBase::getUrlFromWikiLink(const std::string &string) +std::string LLUrlEntryBase::getUrlFromWikiLink(const std::string &string) const { // return the url part from [http://www.example.org Label] const char *text = string.c_str(); @@ -192,7 +192,7 @@ std::string LLUrlEntryHTTPLabel::getLabel(const std::string &url, const LLUrlLab return getLabelFromWikiLink(url); } -std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) +std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) const { return getUrlFromWikiLink(string); } @@ -217,7 +217,7 @@ std::string LLUrlEntryHTTPNoProtocol::getLabel(const std::string &url, const LLU return unescapeUrl(url); } -std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) +std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) const { if (string.find("://") == std::string::npos) { @@ -597,7 +597,7 @@ std::string LLUrlEntrySLLabel::getLabel(const std::string &url, const LLUrlLabel return getLabelFromWikiLink(url); } -std::string LLUrlEntrySLLabel::getUrl(const std::string &string) +std::string LLUrlEntrySLLabel::getUrl(const std::string &string) const { return getUrlFromWikiLink(string); } @@ -648,14 +648,18 @@ std::string LLUrlEntryWorldMap::getLocation(const std::string &url) const // LLUrlEntryNoLink::LLUrlEntryNoLink() { - mPattern = boost::regex("<nolink>[^[:space:]<]+</nolink>", + mPattern = boost::regex("<nolink>[^<]*</nolink>", boost::regex::perl|boost::regex::icase); mDisabledLink = true; } -std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +std::string LLUrlEntryNoLink::getUrl(const std::string &url) const { // return the text between the <nolink> and </nolink> tags return url.substr(8, url.size()-8-9); } +std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + return getUrl(url); +} diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 94455ac247..3abada0f24 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -71,7 +71,7 @@ public: boost::regex getPattern() const { return mPattern; } /// Return the url from a string that matched the regex - virtual std::string getUrl(const std::string &string); + virtual std::string getUrl(const std::string &string) const; /// Given a matched Url, return a label for the Url virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; } @@ -98,8 +98,8 @@ protected: std::string getIDStringFromUrl(const std::string &url) const; std::string escapeUrl(const std::string &url) const; std::string unescapeUrl(const std::string &url) const; - std::string getLabelFromWikiLink(const std::string &url); - std::string getUrlFromWikiLink(const std::string &string); + 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); void callObservers(const std::string &id, const std::string &label); @@ -135,7 +135,7 @@ class LLUrlEntryHTTPLabel : public LLUrlEntryBase public: LLUrlEntryHTTPLabel(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); - /*virtual*/ std::string getUrl(const std::string &string); + /*virtual*/ std::string getUrl(const std::string &string) const; }; /// @@ -146,7 +146,7 @@ class LLUrlEntryHTTPNoProtocol : public LLUrlEntryBase public: LLUrlEntryHTTPNoProtocol(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); - /*virtual*/ std::string getUrl(const std::string &string); + /*virtual*/ std::string getUrl(const std::string &string) const; }; /// @@ -256,7 +256,7 @@ class LLUrlEntrySLLabel : public LLUrlEntryBase public: LLUrlEntrySLLabel(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); - /*virtual*/ std::string getUrl(const std::string &string); + /*virtual*/ std::string getUrl(const std::string &string) const; }; /// @@ -279,6 +279,7 @@ class LLUrlEntryNoLink : public LLUrlEntryBase public: LLUrlEntryNoLink(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getUrl(const std::string &string) const; }; #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 55eb8950e9..722dbe41b3 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -132,7 +132,8 @@ static bool stringHasUrl(const std::string &text) text.find(".com") != std::string::npos || text.find(".net") != std::string::npos || text.find(".edu") != std::string::npos || - text.find(".org") != std::string::npos); + text.find(".org") != std::string::npos || + text.find("<nolink>") != std::string::npos); } bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index bc97cf3df2..cbb303a059 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -52,9 +52,10 @@ namespace namespace tut { - void testRegex(const std::string &testname, boost::regex regex, + void testRegex(const std::string &testname, LLUrlEntryBase &entry, const char *text, const std::string &expected) { + boost::regex regex = entry.getPattern(); std::string url = ""; boost::cmatch result; bool found = boost::regex_search(text, result, regex); @@ -62,7 +63,7 @@ namespace tut { S32 start = static_cast<U32>(result[0].first - text); S32 end = static_cast<U32>(result[0].second - text); - url = std::string(text+start, end-start); + url = entry.getUrl(std::string(text+start, end-start)); } ensure_equals(testname, url, expected); } @@ -74,74 +75,73 @@ namespace tut // test LLUrlEntryHTTP - standard http Urls // LLUrlEntryHTTP url; - boost::regex r = url.getPattern(); - testRegex("no valid url", r, + testRegex("no valid url", url, "htp://slurl.com/", ""); - testRegex("simple http (1)", r, + testRegex("simple http (1)", url, "http://slurl.com/", "http://slurl.com/"); - testRegex("simple http (2)", r, + testRegex("simple http (2)", url, "http://slurl.com", "http://slurl.com"); - testRegex("simple http (3)", r, + testRegex("simple http (3)", url, "http://slurl.com/about.php", "http://slurl.com/about.php"); - testRegex("simple https", r, + testRegex("simple https", url, "https://slurl.com/about.php", "https://slurl.com/about.php"); - testRegex("http in text (1)", r, + testRegex("http in text (1)", url, "XX http://slurl.com/ XX", "http://slurl.com/"); - testRegex("http in text (2)", r, + testRegex("http in text (2)", url, "XX http://slurl.com/about.php XX", "http://slurl.com/about.php"); - testRegex("https in text", r, + testRegex("https in text", url, "XX https://slurl.com/about.php XX", "https://slurl.com/about.php"); - testRegex("two http urls", r, + testRegex("two http urls", url, "XX http://slurl.com/about.php http://secondlife.com/ XX", "http://slurl.com/about.php"); - testRegex("http url with port and username", r, + testRegex("http url with port and username", url, "XX http://nobody@slurl.com:80/about.php http://secondlife.com/ XX", "http://nobody@slurl.com:80/about.php"); - testRegex("http url with port, username, and query string", r, + testRegex("http url with port, username, and query string", url, "XX http://nobody@slurl.com:80/about.php?title=hi%20there http://secondlife.com/ XX", "http://nobody@slurl.com:80/about.php?title=hi%20there"); // note: terminating commas will be removed by LLUrlRegistry:findUrl() - testRegex("http url with commas in middle and terminating", r, + testRegex("http url with commas in middle and terminating", url, "XX http://slurl.com/?title=Hi,There, XX", "http://slurl.com/?title=Hi,There,"); // note: terminating periods will be removed by LLUrlRegistry:findUrl() - testRegex("http url with periods in middle and terminating", r, + testRegex("http url with periods in middle and terminating", url, "XX http://slurl.com/index.php. XX", "http://slurl.com/index.php."); // DEV-19842: Closing parenthesis ")" breaks urls - testRegex("http url with brackets (1)", r, + testRegex("http url with brackets (1)", url, "XX http://en.wikipedia.org/wiki/JIRA_(software) XX", "http://en.wikipedia.org/wiki/JIRA_(software)"); // DEV-19842: Closing parenthesis ")" breaks urls - testRegex("http url with brackets (2)", r, + testRegex("http url with brackets (2)", url, "XX http://jira.secondlife.com/secure/attachment/17990/eggy+avs+in+1.21.0+(93713)+public+nightly.jpg XX", "http://jira.secondlife.com/secure/attachment/17990/eggy+avs+in+1.21.0+(93713)+public+nightly.jpg"); // DEV-10353: URLs in chat log terminated incorrectly when newline in chat - testRegex("http url with newlines", r, + testRegex("http url with newlines", url, "XX\nhttp://www.secondlife.com/\nXX", "http://www.secondlife.com/"); } @@ -153,39 +153,38 @@ namespace tut // test LLUrlEntryHTTPLabel - wiki-style http Urls with labels // LLUrlEntryHTTPLabel url; - boost::regex r = url.getPattern(); - testRegex("invalid wiki url [1]", r, + testRegex("invalid wiki url [1]", url, "[http://www.example.org]", ""); - testRegex("invalid wiki url [2]", r, + testRegex("invalid wiki url [2]", url, "[http://www.example.org", ""); - testRegex("invalid wiki url [3]", r, + testRegex("invalid wiki url [3]", url, "[http://www.example.org Label", ""); - testRegex("example.org with label (spaces)", r, + testRegex("example.org with label (spaces)", url, "[http://www.example.org Text]", - "[http://www.example.org Text]"); + "http://www.example.org"); - testRegex("example.org with label (tabs)", r, + testRegex("example.org with label (tabs)", url, "[http://www.example.org\t Text]", - "[http://www.example.org\t Text]"); + "http://www.example.org"); - testRegex("SL http URL with label", r, + testRegex("SL http URL with label", url, "[http://www.secondlife.com/ Second Life]", - "[http://www.secondlife.com/ Second Life]"); + "http://www.secondlife.com/"); - testRegex("SL https URL with label", r, + testRegex("SL https URL with label", url, "XXX [https://www.secondlife.com/ Second Life] YYY", - "[https://www.secondlife.com/ Second Life]"); + "https://www.secondlife.com/"); - testRegex("SL http URL with label", r, + testRegex("SL http URL with label", url, "[http://www.secondlife.com/?test=Hi%20There Second Life]", - "[http://www.secondlife.com/?test=Hi%20There Second Life]"); + "http://www.secondlife.com/?test=Hi%20There"); } template<> template<> @@ -195,69 +194,68 @@ namespace tut // test LLUrlEntrySLURL - second life URLs // LLUrlEntrySLURL url; - boost::regex r = url.getPattern(); - testRegex("no valid slurl [1]", r, + testRegex("no valid slurl [1]", url, "htp://slurl.com/secondlife/Ahern/50/50/50/", ""); - testRegex("no valid slurl [2]", r, + testRegex("no valid slurl [2]", url, "http://slurl.com/secondlife/", ""); - testRegex("no valid slurl [3]", r, + testRegex("no valid slurl [3]", url, "hhtp://slurl.com/secondlife/Ahern/50/FOO/50/", ""); - testRegex("Ahern (50,50,50) [1]", r, + testRegex("Ahern (50,50,50) [1]", url, "http://slurl.com/secondlife/Ahern/50/50/50/", "http://slurl.com/secondlife/Ahern/50/50/50/"); - testRegex("Ahern (50,50,50) [2]", r, + testRegex("Ahern (50,50,50) [2]", url, "XXX http://slurl.com/secondlife/Ahern/50/50/50/ XXX", "http://slurl.com/secondlife/Ahern/50/50/50/"); - testRegex("Ahern (50,50,50) [3]", r, + testRegex("Ahern (50,50,50) [3]", url, "XXX http://slurl.com/secondlife/Ahern/50/50/50 XXX", "http://slurl.com/secondlife/Ahern/50/50/50"); - testRegex("Ahern (50,50,50) multicase", r, + testRegex("Ahern (50,50,50) multicase", url, "XXX http://SLUrl.com/SecondLife/Ahern/50/50/50/ XXX", "http://SLUrl.com/SecondLife/Ahern/50/50/50/"); - testRegex("Ahern (50,50) [1]", r, + testRegex("Ahern (50,50) [1]", url, "XXX http://slurl.com/secondlife/Ahern/50/50/ XXX", "http://slurl.com/secondlife/Ahern/50/50/"); - testRegex("Ahern (50,50) [2]", r, + testRegex("Ahern (50,50) [2]", url, "XXX http://slurl.com/secondlife/Ahern/50/50 XXX", "http://slurl.com/secondlife/Ahern/50/50"); - testRegex("Ahern (50)", r, + testRegex("Ahern (50)", url, "XXX http://slurl.com/secondlife/Ahern/50 XXX", "http://slurl.com/secondlife/Ahern/50"); - testRegex("Ahern", r, + testRegex("Ahern", url, "XXX http://slurl.com/secondlife/Ahern/ XXX", "http://slurl.com/secondlife/Ahern/"); - testRegex("Ahern SLURL with title", r, + testRegex("Ahern SLURL with title", url, "XXX http://slurl.com/secondlife/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE! XXX", "http://slurl.com/secondlife/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE!"); - testRegex("Ahern SLURL with msg", r, + testRegex("Ahern SLURL with msg", url, "XXX http://slurl.com/secondlife/Ahern/50/50/50/?msg=Your%20text%20here. XXX", "http://slurl.com/secondlife/Ahern/50/50/50/?msg=Your%20text%20here."); // DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat - testRegex("SLURL with brackets", r, + testRegex("SLURL with brackets", url, "XXX http://slurl.com/secondlife/Burning%20Life%20(Hyper)/27/210/30 XXX", "http://slurl.com/secondlife/Burning%20Life%20(Hyper)/27/210/30"); // DEV-35459: SLURLs and teleport Links not parsed properly - testRegex("SLURL with quote", r, + testRegex("SLURL with quote", url, "XXX http://slurl.com/secondlife/A'ksha%20Oasis/41/166/701 XXX", - "http://slurl.com/secondlife/A'ksha%20Oasis/41/166/701"); + "http://slurl.com/secondlife/A%27ksha%20Oasis/41/166/701"); } template<> template<> @@ -267,25 +265,24 @@ namespace tut // test LLUrlEntryAgent - secondlife://app/agent Urls // LLUrlEntryAgent url; - boost::regex r = url.getPattern(); - testRegex("Invalid Agent Url", r, + testRegex("Invalid Agent Url", url, "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about", ""); - testRegex("Agent Url ", r, + testRegex("Agent Url ", url, "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about", "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); - testRegex("Agent Url in text", r, + testRegex("Agent Url in text", url, "XXX secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about XXX", "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); - testRegex("Agent Url multicase", r, + testRegex("Agent Url multicase", url, "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX", "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About"); - testRegex("Agent Url alternate command", r, + testRegex("Agent Url alternate command", url, "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar", "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar"); @@ -298,25 +295,24 @@ namespace tut // test LLUrlEntryGroup - secondlife://app/group Urls // LLUrlEntryGroup url; - boost::regex r = url.getPattern(); - testRegex("Invalid Group Url", r, + testRegex("Invalid Group Url", url, "secondlife:///app/group/00005ff3-4044-c79f-XXXX-fb28ae0df991/about", ""); - testRegex("Group Url ", r, + testRegex("Group Url ", url, "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about", "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about"); - testRegex("Group Url ", r, + testRegex("Group Url ", url, "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect", "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect"); - testRegex("Group Url in text", r, + testRegex("Group Url in text", url, "XXX secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about XXX", "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about"); - testRegex("Group Url multicase", r, + testRegex("Group Url multicase", url, "XXX secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About XXX", "secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About"); } @@ -328,45 +324,44 @@ namespace tut // test LLUrlEntryPlace - secondlife://<location> URLs // LLUrlEntryPlace url; - boost::regex r = url.getPattern(); - testRegex("no valid slurl [1]", r, + testRegex("no valid slurl [1]", url, "secondlife://Ahern/FOO/50/", ""); - testRegex("Ahern (50,50,50) [1]", r, + testRegex("Ahern (50,50,50) [1]", url, "secondlife://Ahern/50/50/50/", "secondlife://Ahern/50/50/50/"); - testRegex("Ahern (50,50,50) [2]", r, + testRegex("Ahern (50,50,50) [2]", url, "XXX secondlife://Ahern/50/50/50/ XXX", "secondlife://Ahern/50/50/50/"); - testRegex("Ahern (50,50,50) [3]", r, + testRegex("Ahern (50,50,50) [3]", url, "XXX secondlife://Ahern/50/50/50 XXX", "secondlife://Ahern/50/50/50"); - testRegex("Ahern (50,50,50) multicase", r, + testRegex("Ahern (50,50,50) multicase", url, "XXX SecondLife://Ahern/50/50/50/ XXX", "SecondLife://Ahern/50/50/50/"); - testRegex("Ahern (50,50) [1]", r, + testRegex("Ahern (50,50) [1]", url, "XXX secondlife://Ahern/50/50/ XXX", "secondlife://Ahern/50/50/"); - testRegex("Ahern (50,50) [2]", r, + testRegex("Ahern (50,50) [2]", url, "XXX secondlife://Ahern/50/50 XXX", "secondlife://Ahern/50/50"); // DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat - testRegex("SLURL with brackets", r, + testRegex("SLURL with brackets", url, "XXX secondlife://Burning%20Life%20(Hyper)/27/210/30 XXX", "secondlife://Burning%20Life%20(Hyper)/27/210/30"); // DEV-35459: SLURLs and teleport Links not parsed properly - testRegex("SLURL with quote", r, + testRegex("SLURL with quote", url, "XXX secondlife://A'ksha%20Oasis/41/166/701 XXX", - "secondlife://A'ksha%20Oasis/41/166/701"); + "secondlife://A%27ksha%20Oasis/41/166/701"); } template<> template<> @@ -376,21 +371,20 @@ namespace tut // test LLUrlEntryParcel - secondlife://app/parcel Urls // LLUrlEntryParcel url; - boost::regex r = url.getPattern(); - testRegex("Invalid Classified Url", r, + testRegex("Invalid Classified Url", url, "secondlife:///app/parcel/0000060e-4b39-e00b-XXXX-d98b1934e3a8/about", ""); - testRegex("Classified Url ", r, + testRegex("Classified Url ", url, "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about", "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about"); - testRegex("Classified Url in text", r, + testRegex("Classified Url in text", url, "XXX secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about XXX", "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about"); - testRegex("Classified Url multicase", r, + testRegex("Classified Url multicase", url, "XXX secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About XXX", "secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About"); } @@ -401,73 +395,72 @@ namespace tut // test LLUrlEntryTeleport - secondlife://app/teleport URLs // LLUrlEntryTeleport url; - boost::regex r = url.getPattern(); - testRegex("no valid teleport [1]", r, + testRegex("no valid teleport [1]", url, "http://slurl.com/secondlife/Ahern/50/50/50/", ""); - testRegex("no valid teleport [2]", r, + testRegex("no valid teleport [2]", url, "secondlife:///app/teleport/", ""); - testRegex("no valid teleport [3]", r, + testRegex("no valid teleport [3]", url, "second-life:///app/teleport/Ahern/50/50/50/", ""); - testRegex("no valid teleport [3]", r, + testRegex("no valid teleport [3]", url, "hhtp://slurl.com/secondlife/Ahern/50/FOO/50/", ""); - testRegex("Ahern (50,50,50) [1]", r, + testRegex("Ahern (50,50,50) [1]", url, "secondlife:///app/teleport/Ahern/50/50/50/", "secondlife:///app/teleport/Ahern/50/50/50/"); - testRegex("Ahern (50,50,50) [2]", r, + testRegex("Ahern (50,50,50) [2]", url, "XXX secondlife:///app/teleport/Ahern/50/50/50/ XXX", "secondlife:///app/teleport/Ahern/50/50/50/"); - testRegex("Ahern (50,50,50) [3]", r, + testRegex("Ahern (50,50,50) [3]", url, "XXX secondlife:///app/teleport/Ahern/50/50/50 XXX", "secondlife:///app/teleport/Ahern/50/50/50"); - testRegex("Ahern (50,50,50) multicase", r, + testRegex("Ahern (50,50,50) multicase", url, "XXX secondlife:///app/teleport/Ahern/50/50/50/ XXX", "secondlife:///app/teleport/Ahern/50/50/50/"); - testRegex("Ahern (50,50) [1]", r, + testRegex("Ahern (50,50) [1]", url, "XXX secondlife:///app/teleport/Ahern/50/50/ XXX", "secondlife:///app/teleport/Ahern/50/50/"); - testRegex("Ahern (50,50) [2]", r, + testRegex("Ahern (50,50) [2]", url, "XXX secondlife:///app/teleport/Ahern/50/50 XXX", "secondlife:///app/teleport/Ahern/50/50"); - testRegex("Ahern (50)", r, + testRegex("Ahern (50)", url, "XXX secondlife:///app/teleport/Ahern/50 XXX", "secondlife:///app/teleport/Ahern/50"); - testRegex("Ahern", r, + testRegex("Ahern", url, "XXX secondlife:///app/teleport/Ahern/ XXX", "secondlife:///app/teleport/Ahern/"); - testRegex("Ahern teleport with title", r, + testRegex("Ahern teleport with title", url, "XXX secondlife:///app/teleport/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE! XXX", "secondlife:///app/teleport/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE!"); - testRegex("Ahern teleport with msg", r, + testRegex("Ahern teleport with msg", url, "XXX secondlife:///app/teleport/Ahern/50/50/50/?msg=Your%20text%20here. XXX", "secondlife:///app/teleport/Ahern/50/50/50/?msg=Your%20text%20here."); // DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat - testRegex("Teleport with brackets", r, + testRegex("Teleport with brackets", url, "XXX secondlife:///app/teleport/Burning%20Life%20(Hyper)/27/210/30 XXX", "secondlife:///app/teleport/Burning%20Life%20(Hyper)/27/210/30"); // DEV-35459: SLURLs and teleport Links not parsed properly - testRegex("Teleport url with quote", r, + testRegex("Teleport url with quote", url, "XXX secondlife:///app/teleport/A'ksha%20Oasis/41/166/701 XXX", - "secondlife:///app/teleport/A'ksha%20Oasis/41/166/701"); + "secondlife:///app/teleport/A%27ksha%20Oasis/41/166/701"); } template<> template<> @@ -477,33 +470,32 @@ namespace tut // test LLUrlEntrySL - general secondlife:// URLs // LLUrlEntrySL url; - boost::regex r = url.getPattern(); - testRegex("no valid slapp [1]", r, + testRegex("no valid slapp [1]", url, "http:///app/", ""); - testRegex("valid slapp [1]", r, + testRegex("valid slapp [1]", url, "secondlife:///app/", "secondlife:///app/"); - testRegex("valid slapp [2]", r, + testRegex("valid slapp [2]", url, "secondlife:///app/teleport/Ahern/50/50/50/", "secondlife:///app/teleport/Ahern/50/50/50/"); - testRegex("valid slapp [3]", r, + testRegex("valid slapp [3]", url, "secondlife:///app/foo", "secondlife:///app/foo"); - testRegex("valid slapp [4]", r, + testRegex("valid slapp [4]", url, "secondlife:///APP/foo?title=Hi%20There", "secondlife:///APP/foo?title=Hi%20There"); - testRegex("valid slapp [5]", r, + testRegex("valid slapp [5]", url, "secondlife://host/app/", "secondlife://host/app/"); - testRegex("valid slapp [6]", r, + testRegex("valid slapp [6]", url, "secondlife://host:8080/foo/bar", "secondlife://host:8080/foo/bar"); } @@ -515,35 +507,34 @@ namespace tut // test LLUrlEntrySLLabel - general secondlife:// URLs with labels // LLUrlEntrySLLabel url; - boost::regex r = url.getPattern(); - testRegex("invalid wiki url [1]", r, + testRegex("invalid wiki url [1]", url, "[secondlife:///app/]", ""); - testRegex("invalid wiki url [2]", r, + testRegex("invalid wiki url [2]", url, "[secondlife:///app/", ""); - testRegex("invalid wiki url [3]", r, + testRegex("invalid wiki url [3]", url, "[secondlife:///app/ Label", ""); - testRegex("agent slurl with label (spaces)", r, + testRegex("agent slurl with label (spaces)", url, "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about Text]", - "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about Text]"); + "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); - testRegex("agent slurl with label (tabs)", r, + testRegex("agent slurl with label (tabs)", url, "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about\t Text]", - "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about\t Text]"); + "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); - testRegex("agent slurl with label", r, + testRegex("agent slurl with label", url, "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about FirstName LastName]", - "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about FirstName LastName]"); + "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); - testRegex("teleport slurl with label", r, + testRegex("teleport slurl with label", url, "XXX [secondlife:///app/teleport/Ahern/50/50/50/ Teleport to Ahern] YYY", - "[secondlife:///app/teleport/Ahern/50/50/50/ Teleport to Ahern]"); + "secondlife:///app/teleport/Ahern/50/50/50/"); } template<> template<> @@ -553,70 +544,98 @@ namespace tut // test LLUrlEntryHTTPNoProtocol - general URLs without a protocol // LLUrlEntryHTTPNoProtocol url; - boost::regex r = url.getPattern(); - testRegex("naked .com URL", r, + testRegex("naked .com URL", url, "see google.com", - "google.com"); + "http://google.com"); - testRegex("naked .org URL", r, + testRegex("naked .org URL", url, "see en.wikipedia.org for details", - "en.wikipedia.org"); + "http://en.wikipedia.org"); - testRegex("naked .net URL", r, + testRegex("naked .net URL", url, "example.net", - "example.net"); + "http://example.net"); - testRegex("naked .edu URL (2 instances)", r, + testRegex("naked .edu URL (2 instances)", url, "MIT web site is at web.mit.edu and also www.mit.edu", - "web.mit.edu"); + "http://web.mit.edu"); - testRegex("don't match e-mail addresses", r, + testRegex("don't match e-mail addresses", url, "test@lindenlab.com", ""); - testRegex(".com URL with path", r, + testRegex(".com URL with path", url, "see secondlife.com/status for grid status", - "secondlife.com/status"); + "http://secondlife.com/status"); - testRegex(".com URL with port", r, + testRegex(".com URL with port", url, "secondlife.com:80", - "secondlife.com:80"); + "http://secondlife.com:80"); - testRegex(".com URL with port and path", r, + testRegex(".com URL with port and path", url, "see secondlife.com:80/status", - "secondlife.com:80/status"); + "http://secondlife.com:80/status"); - testRegex("www.*.com URL with port and path", r, + testRegex("www.*.com URL with port and path", url, "see www.secondlife.com:80/status", - "www.secondlife.com:80/status"); + "http://www.secondlife.com:80/status"); - testRegex("invalid .com URL [1]", r, + testRegex("invalid .com URL [1]", url, "..com", ""); - testRegex("invalid .com URL [2]", r, + testRegex("invalid .com URL [2]", url, "you.come", ""); - testRegex("invalid .com URL [3]", r, + testRegex("invalid .com URL [3]", url, "recommended", ""); - testRegex("invalid .edu URL", r, + testRegex("invalid .edu URL", url, "hi there scheduled maitenance has begun", ""); - testRegex("invalid .net URL", r, + testRegex("invalid .net URL", url, "foo.netty", ""); - testRegex("XML tags around URL [1]", r, + testRegex("XML tags around URL [1]", url, "<foo>secondlife.com</foo>", - "secondlife.com"); + "http://secondlife.com"); - testRegex("XML tags around URL [2]", r, + testRegex("XML tags around URL [2]", url, "<foo>secondlife.com/status?bar=1</foo>", - "secondlife.com/status?bar=1"); + "http://secondlife.com/status?bar=1"); + } + + template<> template<> + void object::test<12>() + { + // + // test LLUrlEntryNoLink - turn off hyperlinking + // + LLUrlEntryNoLink url; + + testRegex("<nolink> [1]", url, + "<nolink>google.com</nolink>", + "google.com"); + + testRegex("<nolink> [2]", url, + "<nolink>google.com", + ""); + + testRegex("<nolink> [3]", url, + "google.com</nolink>", + ""); + + testRegex("<nolink> [4]", url, + "<nolink>Hello World</nolink>", + "Hello World"); + + testRegex("<nolink> [5]", url, + "<nolink>My Object</nolink>", + "My Object"); } } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 581c210bd5..7c22ac9e36 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -579,19 +579,26 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL url += "?name=" + chat.mFromName; url += "&owner=" + args["owner_id"].asString(); - LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); - if (region) + std::string slurl = args["slurl"].asString(); + if (slurl.empty()) { - S32 x, y, z; - LLSLURL::globalPosToXYZ(LLVector3d(chat.mPosAgent), x, y, z); - url += "&slurl=" + region->getName() + llformat("/%d/%d/%d", x, y, z); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); + if (region) + { + S32 x, y, z; + LLSLURL::globalPosToXYZ(LLVector3d(chat.mPosAgent), x, y, z); + slurl = region->getName() + llformat("/%d/%d/%d", x, y, z); + } } + url += "&slurl=" + slurl; // set the link for the object name to be the objectim SLapp + // (don't let object names with hyperlinks override our objectim Url) LLStyle::Params link_params(style_params); link_params.color.control = "HTMLLinkColor"; link_params.link_href = url; - mEditor->appendText(chat.mFromName + delimiter, false, link_params); + mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, + false, link_params); } else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() ) { diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index f7f7ee83af..f772aea4bd 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -258,8 +258,12 @@ BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask) BOOL LLNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask) { + /* + fix for request EXT-4780 + leaving this commented since I don't remember why ew block those messages... if(mSourceType != CHAT_SOURCE_AGENT) return LLPanel::handleMouseUp(x,y,mask); + */ LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); S32 local_x = x - text_box->getRect().mLeft; diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index e0a9e080fa..3818ee6f78 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -116,7 +116,7 @@ LLExpandableTextBox::LLTextBoxEx::Params::Params() } LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p) -: LLTextBox(p), +: LLTextEditor(p), mExpanderLabel(p.more_label), mExpanderVisible(false) { @@ -127,7 +127,7 @@ LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p) void LLExpandableTextBox::LLTextBoxEx::reshape(S32 width, S32 height, BOOL called_from_parent) { hideExpandText(); - LLTextBox::reshape(width, height, called_from_parent); + LLTextEditor::reshape(width, height, called_from_parent); if (getTextPixelHeight() > getRect().getHeight()) { @@ -140,7 +140,7 @@ void LLExpandableTextBox::LLTextBoxEx::setText(const LLStringExplicit& text,cons // LLTextBox::setText will obliterate the expander segment, so make sure // we generate it again by clearing mExpanderVisible mExpanderVisible = false; - LLTextBox::setText(text, input_params); + LLTextEditor::setText(text, input_params); // text contents have changed, segments are cleared out // so hide the expander and determine if we need it @@ -201,6 +201,11 @@ S32 LLExpandableTextBox::LLTextBoxEx::getVerticalTextDelta() return text_height - textbox_height; } +S32 LLExpandableTextBox::LLTextBoxEx::getTextPixelHeight() +{ + return getTextBoundingRect().getHeight(); +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h index 2b4f9e527c..58316ddb98 100644 --- a/indra/newview/llexpandabletextbox.h +++ b/indra/newview/llexpandabletextbox.h @@ -33,7 +33,7 @@ #ifndef LL_LLEXPANDABLETEXTBOX_H #define LL_LLEXPANDABLETEXTBOX_H -#include "lltextbox.h" +#include "lltexteditor.h" #include "llscrollcontainer.h" /** @@ -49,10 +49,10 @@ protected: * Extended text box. "More" link will appear at end of text if * text is too long to fit into text box size. */ - class LLTextBoxEx : public LLTextBox + class LLTextBoxEx : public LLTextEditor { public: - struct Params : public LLInitParam::Block<Params, LLTextBox::Params> + struct Params : public LLInitParam::Block<Params, LLTextEditor::Params> { Mandatory<std::string> more_label; Params(); @@ -70,6 +70,11 @@ protected: virtual S32 getVerticalTextDelta(); /** + * Returns the height of text rect. + */ + S32 getTextPixelHeight(); + + /** * Shows "More" link */ void showExpandText(); diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 784c2eaaf9..22eb9a51d2 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -52,6 +52,7 @@ LLIMFloaterContainer::~LLIMFloaterContainer(){} BOOL LLIMFloaterContainer::postBuild() { + LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1)); // Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button // mTabContainer will be initialized in LLMultiFloater::addChild() return TRUE; @@ -162,6 +163,21 @@ void LLIMFloaterContainer::onCloseFloater(LLUUID id) { LLAvatarPropertiesProcessor::instance().removeObserver(id, this); LLGroupMgr::instance().removeObserver(id, this); + +} + +void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data) +{ + LLUUID session_id = data["from_id"].asUUID(); + LLFloater* floaterp = get_ptr_in_map(mSessions, session_id); + LLFloater* current_floater = LLMultiFloater::getActiveFloater(); + + if(floaterp && current_floater && floaterp != current_floater) + { + if(LLMultiFloater::isFloaterFlashing(floaterp)) + LLMultiFloater::setFloaterFlashing(floaterp, FALSE); + LLMultiFloater::setFloaterFlashing(floaterp, TRUE); + } } LLIMFloaterContainer* LLIMFloaterContainer::findInstance() diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index e4a32dbe1d..bc06f0cbd3 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -66,10 +66,12 @@ public: static LLIMFloaterContainer* getInstance(); private: - typedef std::map<LLUUID,LLPanel*> avatarID_panel_map_t; + typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t; avatarID_panel_map_t mSessions; void onCloseFloater(LLUUID avatar_id); + + void onNewMessageReceived(const LLSD& data); }; #endif // LL_LLIMFLOATERCONTAINER_H diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp index c7b8db9635..c7b651f37c 100644 --- a/indra/newview/llinspect.cpp +++ b/indra/newview/llinspect.cpp @@ -34,6 +34,7 @@ #include "llcontrol.h" // LLCachedControl #include "llui.h" // LLUI::sSettingsGroups +#include "llviewermenu.h" LLInspect::LLInspect(const LLSD& key) : LLFloater(key), @@ -108,3 +109,26 @@ void LLInspect::onMouseLeave(S32 x, S32 y, MASK mask) { mOpenTimer.unpause(); } + +bool LLInspect::childHasVisiblePopupMenu() +{ + // Child text-box may spawn a pop-up menu, if mouse is over the menu, Inspector + // will hide(which is not expected). + // This is an attempt to find out if child control has spawned a menu. + + LLView* child_menu = gMenuHolder->getVisibleMenu(); + if(child_menu) + { + LLRect floater_rc = calcScreenRect(); + LLRect menu_screen_rc = child_menu->calcScreenRect(); + S32 mx, my; + LLUI::getMousePositionScreen(&mx, &my); + + // This works wrong if we spawn a menu near Inspector and menu overlaps Inspector. + if(floater_rc.overlaps(menu_screen_rc) && menu_screen_rc.pointInRect(mx, my)) + { + return true; + } + } + return false; +} diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h index a1cb9cd71c..f8c86618d2 100644 --- a/indra/newview/llinspect.h +++ b/indra/newview/llinspect.h @@ -56,6 +56,9 @@ public: /*virtual*/ void onFocusLost(); protected: + + virtual bool childHasVisiblePopupMenu(); + LLFrameTimer mCloseTimer; LLFrameTimer mOpenTimer; }; diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 3a41aebf28..b2cdc0738f 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -393,11 +393,18 @@ void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask) { LLMenuGL* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu(); LLMenuGL* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu(); - if ( !(gear_menu && gear_menu->getVisible()) && - !(gear_menu_self && gear_menu_self->getVisible())) + if ( gear_menu && gear_menu->getVisible() && + gear_menu_self && gear_menu_self->getVisible() ) { - mOpenTimer.unpause(); + return; + } + + if(childHasVisiblePopupMenu()) + { + return; } + + mOpenTimer.unpause(); } void LLInspectAvatar::updateModeratorPanel() diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index dd313c528d..1a5795a2ae 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -575,10 +575,17 @@ void LLInspectObject::updateSecureBrowsing() void LLInspectObject::onMouseLeave(S32 x, S32 y, MASK mask) { LLMenuGL* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu(); - if ( !(gear_menu && gear_menu->getVisible())) + if ( gear_menu && gear_menu->getVisible() ) { - mOpenTimer.unpause(); + return; + } + + if(childHasVisiblePopupMenu()) + { + return; } + + mOpenTimer.unpause(); } void LLInspectObject::onClickBuy() diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp index 898f1cd9ac..66e4a1bf66 100644 --- a/indra/newview/llinspectremoteobject.cpp +++ b/indra/newview/llinspectremoteobject.cpp @@ -167,7 +167,8 @@ void LLInspectRemoteObject::nameCallback(const LLUUID& id, const std::string& fi void LLInspectRemoteObject::update() { // show the object name as the inspector's title - getChild<LLUICtrl>("object_name")->setValue(mName); + // (don't hyperlink URLs in object names) + getChild<LLUICtrl>("object_name")->setValue("<nolink>" + mName + "</nolink>"); // show the object's owner - click it to show profile std::string owner = mOwner; @@ -192,7 +193,7 @@ void LLInspectRemoteObject::update() std::string url; if (! mSLurl.empty()) { - std::string url = "secondlife:///app/teleport/" + mSLurl; + url = "secondlife:///app/teleport/" + mSLurl; } getChild<LLUICtrl>("object_slurl")->setValue(url); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index e8a4899a0b..f68550d8fd 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3773,6 +3773,21 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode gInventory.updateItem(item); gInventory.notifyObservers(); } + else if("play" == action) + { + if(!LLGestureManager::instance().isGestureActive(mUUID)) + { + // we need to inform server about gesture activating to be consistent with LLPreviewGesture and LLGestureComboList. + BOOL inform_server = TRUE; + BOOL deactivate_similar = FALSE; + LLGestureManager::instance().setGestureLoadedCallback(mUUID, boost::bind(&LLGestureBridge::playGesture, mUUID)); + LLGestureManager::instance().activateGestureWithAsset(mUUID, gInventory.getItem(mUUID)->getAssetUUID(), inform_server, deactivate_similar); + } + else + { + playGesture(mUUID); + } + } else LLItemBridge::performAction(folder, model, action); } @@ -3858,6 +3873,20 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } +// static +void LLGestureBridge::playGesture(const LLUUID& item_id) +{ + if (LLGestureManager::instance().isGesturePlaying(item_id)) + { + LLGestureManager::instance().stopGesture(item_id); + } + else + { + LLGestureManager::instance().playGesture(item_id); + } +} + + // +=================================================+ // | LLAnimationBridge | // +=================================================+ diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index eeb8246b11..6fffec96a0 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -491,6 +491,8 @@ public: virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + static void playGesture(const LLUUID& item_id); + protected: LLGestureBridge(LLInventoryPanel* inventory, const LLUUID& uuid) : LLItemBridge(inventory, uuid) {} diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index dc187bf36c..96ce01c05f 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -138,16 +138,20 @@ void LLLogChat::saveHistory(const std::string& filename, const LLUUID& from_id, const std::string& line) { - if(!filename.size()) + std::string tmp_filename = filename; + LLStringUtil::trim(tmp_filename); + if (tmp_filename.empty()) { - llinfos << "Filename is Empty!" << llendl; + std::string warn = "Chat history filename [" + filename + "] is empty!"; + llwarning(warn, 666); + llassert(tmp_filename.size()); return; } - + llofstream file (LLLogChat::makeLogFileName(filename), std::ios_base::app); if (!file.is_open()) { - llinfos << "Couldn't open chat history log!" << llendl; + llwarns << "Couldn't open chat history log! - " + filename << llendl; return; } diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 71dc0f9011..59708fcfb5 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -34,6 +34,8 @@ #include "llnavigationbar.h" +#include "v2math.h" + #include "llregionhandle.h" #include "llfloaterreg.h" @@ -181,6 +183,77 @@ void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask) mArrowIcon->setVisible(FALSE); } +static LLDefaultChildRegistry::Register<LLPullButton> menu_button("pull_button"); + +LLPullButton::LLPullButton(const LLPullButton::Params& params): + LLButton(params) + , mClickDraggingSignal(NULL) +{ + setDirectionFromName(params.direction); +} +boost::signals2::connection LLPullButton::setClickDraggingCallback( const commit_signal_t::slot_type& cb ) +{ + if (!mClickDraggingSignal) mClickDraggingSignal = new commit_signal_t(); + return mClickDraggingSignal->connect(cb); +} + +/*virtual*/ +void LLPullButton::onMouseLeave(S32 x, S32 y, MASK mask) +{ + LLButton::onMouseLeave(x, y, mask); + + if(mMouseDownTimer.getStarted() ) + { + const LLVector2 cursor_direction = LLVector2(F32(x),F32(y)) - mLastMouseDown; + if( angle_between(mDraggingDirection, cursor_direction) < 0.5 * F_PI_BY_TWO)//call if angle < pi/4 + { + if(mClickDraggingSignal) + { + (*mClickDraggingSignal)(this, LLSD()); + } + } + } + +} + +/*virtual*/ +BOOL LLPullButton::handleMouseDown(S32 x, S32 y, MASK mask) + { + BOOL handled = LLButton::handleMouseDown(x,y, mask); + if(handled) + { + mLastMouseDown.set(F32(x), F32(y)); + } + return handled; +} + +/*virtual*/ +BOOL LLPullButton::handleMouseUp(S32 x, S32 y, MASK mask) +{ + mLastMouseDown.clear(); + return LLButton::handleMouseUp(x, y, mask); +} + +void LLPullButton::setDirectionFromName(const std::string& name) +{ + if (name == "left") + { + mDraggingDirection.set(F32(-1), F32(0)); + } + else if (name == "right") + { + mDraggingDirection.set(F32(0), F32(1)); + } + else if (name == "down") + { + mDraggingDirection.set(F32(0), F32(-1)); + } + else if (name == "up") + { + mDraggingDirection.set(F32(0), F32(1)); + } +} + //-- LNavigationBar ---------------------------------------------------------- /* @@ -215,8 +288,8 @@ LLNavigationBar::~LLNavigationBar() BOOL LLNavigationBar::postBuild() { - mBtnBack = getChild<LLButton>("back_btn"); - mBtnForward = getChild<LLButton>("forward_btn"); + mBtnBack = getChild<LLPullButton>("back_btn"); + mBtnForward = getChild<LLPullButton>("forward_btn"); mBtnHome = getChild<LLButton>("home_btn"); mCmbLocation= getChild<LLLocationInputCtrl>("location_combo"); @@ -224,20 +297,15 @@ BOOL LLNavigationBar::postBuild() fillSearchComboBox(); - if (!mBtnBack || !mBtnForward || !mBtnHome || - !mCmbLocation || !mSearchComboBox) - { - llwarns << "Malformed navigation bar" << llendl; - return FALSE; - } - mBtnBack->setEnabled(FALSE); mBtnBack->setClickedCallback(boost::bind(&LLNavigationBar::onBackButtonClicked, this)); - mBtnBack->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2)); - + mBtnBack->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this,_1, _2)); + mBtnBack->setClickDraggingCallback(boost::bind(&LLNavigationBar::showTeleportHistoryMenu, this,_1)); + mBtnForward->setEnabled(FALSE); mBtnForward->setClickedCallback(boost::bind(&LLNavigationBar::onForwardButtonClicked, this)); - mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2)); + mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _1, _2)); + mBtnForward->setClickDraggingCallback(boost::bind(&LLNavigationBar::showTeleportHistoryMenu, this,_1)); mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this)); @@ -332,10 +400,10 @@ void LLNavigationBar::onBackButtonClicked() LLTeleportHistory::getInstance()->goBack(); } -void LLNavigationBar::onBackOrForwardButtonHeldDown(const LLSD& param) +void LLNavigationBar::onBackOrForwardButtonHeldDown(LLUICtrl* ctrl, const LLSD& param) { if (param["count"].asInteger() == 0) - showTeleportHistoryMenu(); + showTeleportHistoryMenu(ctrl); } void LLNavigationBar::onForwardButtonClicked() @@ -571,7 +639,7 @@ void LLNavigationBar::onRegionNameResponse( gAgent.teleportViaLocation(global_pos); } -void LLNavigationBar::showTeleportHistoryMenu() +void LLNavigationBar::showTeleportHistoryMenu(LLUICtrl* btn_ctrl) { // Don't show the popup if teleport history is empty. if (LLTeleportHistory::getInstance()->isEmpty()) @@ -585,14 +653,43 @@ void LLNavigationBar::showTeleportHistoryMenu() if (mTeleportHistoryMenu == NULL) return; - // *TODO: why to draw/update anything before showing the menu? - mTeleportHistoryMenu->buildDrawLabels(); mTeleportHistoryMenu->updateParent(LLMenuGL::sMenuContainer); const S32 MENU_SPAWN_PAD = -1; - LLMenuGL::showPopup(mBtnBack, mTeleportHistoryMenu, 0, MENU_SPAWN_PAD); - + LLMenuGL::showPopup(btn_ctrl, mTeleportHistoryMenu, 0, MENU_SPAWN_PAD); + LLButton* nav_button = dynamic_cast<LLButton*>(btn_ctrl); + if(nav_button) + { + if(mHistoryMenuConnection.connected()) + { + LL_WARNS("Navgationbar")<<"mHistoryMenuConnection should be disconnected at this moment."<<LL_ENDL; + mHistoryMenuConnection.disconnect(); + } + mHistoryMenuConnection = gMenuHolder->setMouseUpCallback(boost::bind(&LLNavigationBar::onNavigationButtonHeldUp, this, nav_button)); + // pressed state will be update after mouseUp in onBackOrForwardButtonHeldUp(); + nav_button->setForcePressedState(true); + } // *HACK pass the mouse capturing to the drop-down menu - gFocusMgr.setMouseCapture( NULL ); + // it need to let menu handle mouseup event + gFocusMgr.setMouseCapture(gMenuHolder); +} +/** + * Taking into account the HACK above, this callback-function is responsible for correct handling of mouseUp event in case of holding-down the navigation buttons.. + * We need to process this case separately to update a pressed state of navigation button. + */ +void LLNavigationBar::onNavigationButtonHeldUp(LLButton* nav_button) +{ + if(nav_button) + { + nav_button->setForcePressedState(false); + } + if(gFocusMgr.getMouseCapture() == gMenuHolder) + { + // we had passed mouseCapture in showTeleportHistoryMenu() + // now we MUST release mouseCapture to continue a proper mouseevent workflow. + gFocusMgr.setMouseCapture(NULL); + } + //gMenuHolder is using to display bunch of menus. Disconnect signal to avoid unnecessary calls. + mHistoryMenuConnection.disconnect(); } void LLNavigationBar::handleLoginComplete() diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 9d0687f193..9d0abc7a3a 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -34,14 +34,61 @@ #define LL_LLNAVIGATIONBAR_H #include "llpanel.h" +#include "llbutton.h" -class LLButton; class LLLocationInputCtrl; class LLMenuGL; class LLSearchEditor; class LLSearchComboBox; /** + * This button is able to handle click-dragging mouse event. + * It has appropriated signal for this event. + * Dragging direction can be set from xml by attribute called 'direction' + * + * *TODO: move to llui? + */ + +class LLPullButton : public LLButton +{ + LOG_CLASS(LLPullButton); + +public: + + struct Params : public LLInitParam::Block<Params, LLButton::Params> + { + Optional<std::string> direction; // left, right, down, up + + Params() + : direction("direction","down") + {} + }; + + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); + + boost::signals2::connection setClickDraggingCallback( const commit_signal_t::slot_type& cb ); + + /* virtual*/ ~LLPullButton() + { + delete mClickDraggingSignal; + } + +protected: + friend class LLUICtrlFactory; + // convert string name into direction vector + void setDirectionFromName(const std::string& name); + LLPullButton(const LLPullButton::Params& params); + + commit_signal_t* mClickDraggingSignal; + LLVector2 mLastMouseDown; + LLVector2 mDraggingDirection; +}; + +/** * Web browser-like navigation bar. */ class LLNavigationBar @@ -70,13 +117,14 @@ public: private: void rebuildTeleportHistoryMenu(); - void showTeleportHistoryMenu(); + void showTeleportHistoryMenu(LLUICtrl* btn_ctrl); void invokeSearch(std::string search_text); // callbacks void onTeleportHistoryMenuItemClicked(const LLSD& userdata); void onTeleportHistoryChanged(); void onBackButtonClicked(); - void onBackOrForwardButtonHeldDown(const LLSD& param); + void onBackOrForwardButtonHeldDown(LLUICtrl* ctrl, const LLSD& param); + void onNavigationButtonHeldUp(LLButton* nav_button); void onForwardButtonClicked(); void onHomeButtonClicked(); void onLocationSelection(); @@ -94,8 +142,8 @@ private: void fillSearchComboBox(); LLMenuGL* mTeleportHistoryMenu; - LLButton* mBtnBack; - LLButton* mBtnForward; + LLPullButton* mBtnBack; + LLPullButton* mBtnForward; LLButton* mBtnHome; LLSearchComboBox* mSearchComboBox; LLLocationInputCtrl* mCmbLocation; @@ -103,6 +151,7 @@ private: LLRect mDefaultFpRect; boost::signals2::connection mTeleportFailedConnection; boost::signals2::connection mTeleportFinishConnection; + boost::signals2::connection mHistoryMenuConnection; bool mPurgeTPHistoryItems; // if true, save location to location history when teleport finishes bool mSaveToLocationHistory; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 90482eb74d..6de47fccd2 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -62,6 +62,12 @@ static const S32 RESIZE_BAR_THICKNESS = 3; +const static std::string IM_TIME("time"); +const static std::string IM_TEXT("message"); +const static std::string IM_FROM("from"); +const static std::string IM_FROM_ID("from_id"); + + LLNearbyChat::LLNearbyChat(const LLSD& key) : LLDockableFloater(NULL, false, false, key) ,mChatHistory(NULL) @@ -194,6 +200,18 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) mMessageArchive.push_back(chat); if(mMessageArchive.size()>200) mMessageArchive.erase(mMessageArchive.begin()); + + if (gSavedPerAccountSettings.getBOOL("LogChat")) + { + if (chat.mChatType != CHAT_TYPE_WHISPER && chat.mChatType != CHAT_TYPE_SHOUT) + { + LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText); + } + else + { + LLLogChat::saveHistory("chat", "", chat.mFromID, chat.mFromName + " " + chat.mText); + } + } } } @@ -262,6 +280,39 @@ void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue) nearby_chat->updateChatHistoryStyle(); } +void LLNearbyChat::loadHistory() +{ + std::list<LLSD> history; + LLLogChat::loadAllHistory("chat", history); + + std::list<LLSD>::const_iterator it = history.begin(); + while (it != history.end()) + { + const LLSD& msg = *it; + + std::string from = msg[IM_FROM]; + LLUUID from_id = LLUUID::null; + if (msg[IM_FROM_ID].isUndefined()) + { + gCacheName->getUUID(from, from_id); + } + + LLChat chat; + chat.mFromName = from; + chat.mFromID = from_id; + chat.mText = msg[IM_TEXT].asString(); + chat.mTimeStr = msg[IM_TIME].asString(); + addMessage(chat); + + it++; + } +} + +//static +LLNearbyChat* LLNearbyChat::getInstance() +{ + return LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); +} //////////////////////////////////////////////////////////////////////////////// // @@ -278,3 +329,4 @@ void LLNearbyChat::onFocusLost() setBackgroundOpaque(false); LLPanel::onFocusLost(); } + diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 5fb8ade19e..6ef2a1fee3 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -47,6 +47,8 @@ public: ~LLNearbyChat(); BOOL postBuild (); + + /** @param archive true - to save a message to the chat history log */ void addMessage (const LLChat& message,bool archive = true, const LLSD &args = LLSD()); void onNearbyChatContextMenuItemClicked(const LLSD& userdata); bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); @@ -65,6 +67,10 @@ public: static void processChatHistoryStyleUpdate(const LLSD& newvalue); + void loadHistory(); + + static LLNearbyChat* getInstance(); + private: virtual void applySavedVariables(); diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index e2a748a1c5..b8e0892b02 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -168,6 +168,12 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi session_name = "chat"; } + //there still appears a log history file with weird name " .txt" + if (" " == session_name || "{waiting}" == session_name || "{nobody}" == session_name) + { + llwarning("Weird session name (" + session_name + ") for notification " + notification->getName(), 666) + } + if(to_file_only) { logToIM(IM_NOTHING_SPECIAL, session_name, name, notification->getMessage(), diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 3f5d80c123..1e46827c1a 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -1231,12 +1231,14 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t static std::string mature_str = getString("type_mature"); static std::string pg_str = getString("type_pg"); + static LLUIString price_str = getString("l$_price"); bool mature = is_cf_mature(c_info->flags); childSetValue("content_type", mature ? mature_str : pg_str); childSetValue("auto_renew", is_cf_auto_renew(c_info->flags)); - childSetTextArg("price_for_listing", "[PRICE]", llformat("%d", c_info->price_for_listing)); + price_str.setArg("[PRICE]", llformat("%d", c_info->price_for_listing)); + childSetValue("price_for_listing", LLSD(price_str)); setInfoLoaded(true); } diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 29cfbbe606..a49386cb5c 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -70,6 +70,7 @@ #include "lltoggleablemenu.h" #include "llviewerinventory.h" #include "llviewermenu.h" +#include "llviewermessage.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerwindow.h" @@ -105,22 +106,35 @@ private: LLPanelPlaces* mPlaces; }; -class LLPlacesInventoryObserver : public LLInventoryObserver +class LLPlacesInventoryObserver : public LLInventoryAddedObserver { public: LLPlacesInventoryObserver(LLPanelPlaces* places_panel) : - LLInventoryObserver(), - mPlaces(places_panel) + mPlaces(places_panel), + mTabsCreated(false) {} /*virtual*/ void changed(U32 mask) { - if (mPlaces) - mPlaces->changedInventory(mask); + LLInventoryAddedObserver::changed(mask); + + if (!mTabsCreated && mPlaces) + { + mPlaces->createTabs(); + mTabsCreated = true; + } + } + +protected: + /*virtual*/ void done() + { + mPlaces->showAddedLandmarkInfo(mAdded); + mAdded.clear(); } private: LLPanelPlaces* mPlaces; + bool mTabsCreated; }; class LLPlacesRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver @@ -943,7 +957,7 @@ void LLPanelPlaces::changedParcelSelection() updateVerbs(); } -void LLPanelPlaces::changedInventory(U32 mask) +void LLPanelPlaces::createTabs() { if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance())) return; @@ -979,10 +993,6 @@ void LLPanelPlaces::changedInventory(U32 mask) // Filter applied to show all items. if (mActivePanel) mActivePanel->onSearchEdit(mActivePanel->getFilterSubString()); - - // we don't need to monitor inventory changes anymore, - // so remove the observer - gInventory.removeObserver(mInventoryObserver); } void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos) @@ -991,6 +1001,33 @@ void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos) updateVerbs(); } +void LLPanelPlaces::showAddedLandmarkInfo(const std::vector<LLUUID>& items) +{ + for (std::vector<LLUUID>::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) + { + const LLUUID& item_id = (*item_iter); + if(!highlight_offered_item(item_id)) + { + continue; + } + + LLInventoryItem* item = gInventory.getItem(item_id); + + if (LLAssetType::AT_LANDMARK == item->getType()) + { + // Created landmark is passed to Places panel to allow its editing. + // If the panel is closed we don't reopen it until created landmark is loaded. + if("create_landmark" == getPlaceInfoType() && !getItem()) + { + setItem(item); + } + break; + } + } +} + void LLPanelPlaces::updateVerbs() { bool is_place_info_visible; diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 110d7a1054..78fcbbb11d 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -66,11 +66,15 @@ public: // Called on parcel selection change to update place information. void changedParcelSelection(); - // Called on agent inventory change to find out when inventory gets usable. - void changedInventory(U32 mask); + // Called once on agent inventory first change to find out when inventory gets usable + // and to create "My Landmarks" and "Teleport History" tabs. + void createTabs(); // Called when we receive the global 3D position of a parcel. void changedGlobalPos(const LLVector3d &global_pos); + // Opens landmark info panel when agent creates or receives landmark. + void showAddedLandmarkInfo(const std::vector<LLUUID>& items); + void setItem(LLInventoryItem* item); LLInventoryItem* getItem() { return mItem; } diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index f83f3eba96..ad47e351ee 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -583,7 +583,8 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(co bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata) { std::string item = userdata.asString(); - if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item) + if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item + || "can_pay" == item || "can_add" == item) { return mUUIDs.front() != gAgentID; } diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index a00b6a9288..8f36c0e88a 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -487,10 +487,21 @@ void LLScreenChannel::showToastsBottom() toast_rect.setOriginAndSize(getRect().mLeft, bottom + toast_margin, toast_rect.getWidth() ,toast_rect.getHeight()); (*it).toast->setRect(toast_rect); - // don't show toasts if there is not enough space if(floater && floater->overlapsScreenChannel()) { + if(it == mToastList.rbegin()) + { + // move first toast above docked floater + S32 shift = floater->getRect().getHeight(); + if(floater->getDockControl()) + { + shift += floater->getDockControl()->getTongueHeight(); + } + (*it).toast->translate(0, shift); + } + LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); + // don't show toasts if there is not enough space if(toast_rect.mTop > world_rect.mTop) { break; @@ -802,16 +813,6 @@ void LLScreenChannel::updateShowToastsState() S32 channel_bottom = gViewerWindow->getWorldViewRectScaled().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");; LLRect this_rect = getRect(); - // adjust channel's height - if(floater->overlapsScreenChannel()) - { - channel_bottom += floater->getRect().getHeight(); - if(floater->getDockControl()) - { - channel_bottom += floater->getDockControl()->getTongueHeight(); - } - } - if(channel_bottom != this_rect.mBottom) { setRect(LLRect(this_rect.mLeft, this_rect.mTop, this_rect.mRight, channel_bottom)); diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 5383158cd3..7b923f4b0b 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -164,7 +164,21 @@ void LLSidepanelInventory::onWearButtonClicked() void LLSidepanelInventory::onPlayButtonClicked() { - performActionOnSelection("activate"); + const LLInventoryItem *item = getSelectedItem(); + if (!item) + { + return; + } + + switch(item->getInventoryType()) + { + case LLInventoryType::IT_GESTURE: + performActionOnSelection("play"); + break; + default: + performActionOnSelection("activate"); + break; + } } void LLSidepanelInventory::onTeleportButtonClicked() diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6b816f8786..522adc05ce 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -67,6 +67,7 @@ #include "llmemorystream.h" #include "llmessageconfig.h" #include "llmoveview.h" +#include "llnearbychat.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llteleporthistory.h" @@ -904,7 +905,8 @@ bool idle_startup() LLFile::mkdir(gDirUtilp->getChatLogsDir()); LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); - //good as place as any to create user windlight directories + + //good a place as any to create user windlight directories std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", "")); LLFile::mkdir(user_windlight_path_name.c_str()); @@ -1284,6 +1286,14 @@ bool idle_startup() LLAppViewer::instance()->loadNameCache(); } + //gCacheName is required for nearby chat history loading + //so I just moved nearby history loading a few states further + if (!gNoRender && gSavedPerAccountSettings.getBOOL("LogShowHistory")) + { + LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); + if (nearby_chat) nearby_chat->loadHistory(); + } + // *Note: this is where gWorldMap used to be initialized. // register null callbacks for audio until the audio system is initialized diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index b0952dd698..adbe28e9a7 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -860,28 +860,12 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f ++item_iter) { const LLUUID& item_id = (*item_iter); - LLInventoryItem* item = gInventory.getItem(item_id); - if(!item) + if(!highlight_offered_item(item_id)) { - LL_WARNS("Messaging") << "Unable to show inventory item: " << item_id << LL_ENDL; continue; } - //////////////////////////////////////////////////////////////////////////////// - // Don't highlight if it's in certain "quiet" folders which don't need UI - // notification (e.g. trash, cof, lost-and-found). - if(!gAgent.getAFK()) - { - const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(item_id); - if (parent) - { - const LLFolderType::EType parent_type = parent->getPreferredType(); - if (LLViewerFolderType::lookupIsQuietType(parent_type)) - { - continue; - } - } - } + LLInventoryItem* item = gInventory.getItem(item_id); //////////////////////////////////////////////////////////////////////////////// // Special handling for various types. @@ -928,10 +912,11 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f LLPanelPlaces *places_panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->getPanel("panel_places")); if (places_panel) { - // we are creating a landmark + // Landmark creation handling is moved to LLPanelPlaces::showAddedLandmarkInfo() + // TODO* LLPanelPlaces dependency is going to be removed. See EXT-4347. if("create_landmark" == places_panel->getPlaceInfoType() && !places_panel->getItem()) { - places_panel->setItem(item); + //places_panel->setItem(item); } // we are opening a group notice attachment else @@ -981,6 +966,34 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f } } +bool highlight_offered_item(const LLUUID& item_id) +{ + LLInventoryItem* item = gInventory.getItem(item_id); + if(!item) + { + LL_WARNS("Messaging") << "Unable to show inventory item: " << item_id << LL_ENDL; + return false; + } + + //////////////////////////////////////////////////////////////////////////////// + // Don't highlight if it's in certain "quiet" folders which don't need UI + // notification (e.g. trash, cof, lost-and-found). + if(!gAgent.getAFK()) + { + const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(item_id); + if (parent) + { + const LLFolderType::EType parent_type = parent->getPreferredType(); + if (LLViewerFolderType::lookupIsQuietType(parent_type)) + { + return false; + } + } + } + + return true; +} + void inventory_offer_mute_callback(const LLUUID& blocked_id, const std::string& first_name, const std::string& last_name, @@ -2189,7 +2202,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); if(nearby_chat) { - nearby_chat->addMessage(chat); + LLSD args; + args["owner_id"] = from_id; + args["slurl"] = location; + nearby_chat->addMessage(chat, true, args); } diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index 1415c16090..7dd629dcfd 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -203,6 +203,11 @@ void process_initiate_download(LLMessageSystem* msg, void**); void start_new_inventory_observer(); void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& from_name); +// Returns true if item is not in certain "quiet" folder which don't need UI +// notification (e.g. trash, cof, lost-and-found) and agent is not AFK, false otherwise. +// Returns false if item is not found. +bool highlight_offered_item(const LLUUID& item_id); + struct LLOfferInfo { LLOfferInfo() diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 3914064d72..73e1b312fa 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -5982,7 +5982,7 @@ bool LLVoiceClient::voiceEnabled() bool LLVoiceClient::voiceWorking() { - return (stateLoggedIn <= mState) && (mState <= stateLeavingSession); + return (stateLoggedIn <= mState) && (mState <= stateSessionTerminated); } void LLVoiceClient::setLipSyncEnabled(BOOL enabled) diff --git a/indra/newview/skins/default/textures/build/Object_Cone_Selected.png b/indra/newview/skins/default/textures/build/Object_Cone_Selected.png Binary files differnew file mode 100644 index 0000000000..d50dc69ffe --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Cone_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Cube_Selected.png b/indra/newview/skins/default/textures/build/Object_Cube_Selected.png Binary files differnew file mode 100644 index 0000000000..3d6964530d --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Cube_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png b/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png Binary files differnew file mode 100644 index 0000000000..3ed0389961 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Grass_Selected.png b/indra/newview/skins/default/textures/build/Object_Grass_Selected.png Binary files differnew file mode 100644 index 0000000000..3ebd5ea7a1 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Grass_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png Binary files differnew file mode 100644 index 0000000000..3bdc4d1fd5 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png Binary files differnew file mode 100644 index 0000000000..0912442e29 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png Binary files differnew file mode 100644 index 0000000000..33db4a2de8 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Prism_Selected.png b/indra/newview/skins/default/textures/build/Object_Prism_Selected.png Binary files differnew file mode 100644 index 0000000000..9e80fe2b84 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Prism_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png b/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png Binary files differnew file mode 100644 index 0000000000..d36bfa55d4 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Ring_Selected.png b/indra/newview/skins/default/textures/build/Object_Ring_Selected.png Binary files differnew file mode 100644 index 0000000000..962f6efb93 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Ring_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png b/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png Binary files differnew file mode 100644 index 0000000000..715d597144 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png b/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png Binary files differnew file mode 100644 index 0000000000..b2ea680f23 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Torus_Selected.png b/indra/newview/skins/default/textures/build/Object_Torus_Selected.png Binary files differnew file mode 100644 index 0000000000..1fc22686eb --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Torus_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tree_Selected.png b/indra/newview/skins/default/textures/build/Object_Tree_Selected.png Binary files differnew file mode 100644 index 0000000000..5bd87f8a2f --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Tree_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tube_Selected.png b/indra/newview/skins/default/textures/build/Object_Tube_Selected.png Binary files differnew file mode 100644 index 0000000000..a4c3f39e14 --- /dev/null +++ b/indra/newview/skins/default/textures/build/Object_Tube_Selected.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 60c1470b89..ea66897b35 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -321,20 +321,35 @@ with the same filename but different name <texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" /> <texture name="Object_Cone" file_name="build/Object_Cone.png" preload="false" /> + <texture name="Object_Cone_Selected" file_name="build/Object_Cone_Selected.png" preload="false" /> <texture name="Object_Cube" file_name="build/Object_Cube.png" preload="false" /> + <texture name="Object_Cube_Selected" file_name="build/Object_Cube_Selected.png" preload="false" /> <texture name="Object_Cylinder" file_name="build/Object_Cylinder.png" preload="false" /> + <texture name="Object_Cylinder_Selected" file_name="build/Object_Cylinder_Selected.png" preload="false" /> <texture name="Object_Grass" file_name="build/Object_Grass.png" preload="false" /> + <texture name="Object_Grass_Selected" file_name="build/Object_Grass_Selected.png" preload="false" /> <texture name="Object_Hemi_Cone" file_name="build/Object_Hemi_Cone.png" preload="false" /> + <texture name="Object_Hemi_Cone_Selected" file_name="build/Object_Hemi_Cone_Selected.png" preload="false" /> <texture name="Object_Hemi_Cylinder" file_name="build/Object_Hemi_Cylinder.png" preload="false" /> + <texture name="Object_Hemi_Cylinder_Selected" file_name="build/Object_Hemi_Cylinder_Selected.png" preload="false" /> <texture name="Object_Hemi_Sphere" file_name="build/Object_Hemi_Sphere.png" preload="false" /> + <texture name="Object_Hemi_Sphere_Selected" file_name="build/Object_Hemi_Sphere_Selected.png" preload="false" /> <texture name="Object_Prism" file_name="build/Object_Prism.png" preload="false" /> + <texture name="Object_Prism_Selected" file_name="build/Object_Prism_Selected.png" preload="false" /> <texture name="Object_Pyramid" file_name="build/Object_Pyramid.png" preload="false" /> + <texture name="Object_Pyramid_Selected" file_name="build/Object_Pyramid_Selected.png" preload="false" /> <texture name="Object_Ring" file_name="build/Object_Ring.png" preload="false" /> + <texture name="Object_Ring_Selected" file_name="build/Object_Ring_Selected.png" preload="false" /> <texture name="Object_Sphere" file_name="build/Object_Sphere.png" preload="false" /> + <texture name="Object_Sphere_Selected" file_name="build/Object_Sphere_Selected.png" preload="false" /> <texture name="Object_Tetrahedron" file_name="build/Object_Tetrahedron.png" preload="false" /> + <texture name="Object_Tetrahedron_Selected" file_name="build/Object_Tetrahedron_Selected.png" preload="false" /> <texture name="Object_Torus" file_name="build/Object_Torus.png" preload="false" /> + <texture name="Object_Torus_Selected" file_name="build/Object_Torus_Selected.png" preload="false" /> <texture name="Object_Tree" file_name="build/Object_Tree.png" preload="false" /> + <texture name="Object_Tree_Selected" file_name="build/Object_Tree_Selected.png" preload="false" /> <texture name="Object_Tube" file_name="build/Object_Tube.png" preload="false" /> + <texture name="Object_Tube_Selected" file_name="build/Object_Tube_Selected.png" preload="false" /> <texture name="OptionsMenu_Disabled" file_name="icons/OptionsMenu_Disabled.png" preload="false" /> <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" /> @@ -585,10 +600,15 @@ with the same filename but different name scale.left="4" scale.top="28" scale.right="60" scale.bottom="4" /> <texture name="Tool_Create" file_name="build/Tool_Create.png" preload="false" /> + <texture name="Tool_Create_Selected" file_name="build/Tool_Create_Selected.png" preload="false" /> <texture name="Tool_Dozer" file_name="build/Tool_Dozer.png" preload="false" /> + <texture name="Tool_Dozer_Selected" file_name="build/Tool_Dozer_Selected.png" preload="false" /> <texture name="Tool_Face" file_name="build/Tool_Face.png" preload="false" /> + <texture name="Tool_Face_Selected" file_name="build/Tool_Face_Selected.png" preload="false" /> <texture name="Tool_Grab" file_name="build/Tool_Grab.png" preload="false" /> + <texture name="Tool_Grab_Selected" file_name="build/Tool_Grab_Selected.png" preload="false" /> <texture name="Tool_Zoom" file_name="build/Tool_Zoom.png" preload="false" /> + <texture name="Tool_Zoom_Selected" file_name="build/Tool_Zoom_Selected.png" preload="false" /> <texture name="Toolbar_Divider" file_name="containers/Toolbar_Divider.png" preload="false" /> <texture name="Toolbar_Left_Off" file_name="containers/Toolbar_Left_Off.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" /> diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml index 7236351f2e..b9bc45a10b 100644 --- a/indra/newview/skins/default/xui/en/floater_aaa.xml +++ b/indra/newview/skins/default/xui/en/floater_aaa.xml @@ -19,7 +19,7 @@ width="320"> <string name="nudge_parabuild" translate="false">Nudge 1</string> <string name="test_the_vlt">This string CHANGE2 is extracted.</string> - <string name="testing_eli">Just a test. change here. more change.</string> + <string name="testing_eli">Just a test. changes.</string> <chat_history allow_html="true" bg_readonly_color="ChatHistoryBgColor" diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml index 455018f467..d09a0a0535 100644 --- a/indra/newview/skins/default/xui/en/floater_pay_object.xml +++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml @@ -36,7 +36,7 @@ top_delta="3" name="payee_name" width="184"> - Ericacita Moostopolison + [FIRST] [LAST] </text> <text type="string" diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index 60c9810e95..2c9402f6cb 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -46,8 +46,11 @@ <ui_ctrl height="90" width="90" + layout="topleft" name="thumbnail_placeholder" top_pad="6" + follows="left|top" + left="10" /> <text type="string" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index f1aa5c27c1..5630dfbe8f 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -70,7 +70,7 @@ height="20" image_disabled="Tool_Zoom" image_disabled_selected="Tool_Zoom" - image_selected="Tool_Zoom" + image_selected="Tool_Zoom_Selected" image_unselected="Tool_Zoom" layout="topleft" left="10" @@ -86,7 +86,7 @@ height="20" image_disabled="Tool_Grab" image_disabled_selected="Tool_Grab" - image_selected="Tool_Grab" + image_selected="Tool_Grab_Selected" image_unselected="Tool_Grab" layout="topleft" left_pad="20" @@ -102,7 +102,7 @@ height="20" image_disabled="Tool_Face" image_disabled_selected="Tool_Face" - image_selected="Tool_Face" + image_selected="Tool_Face_Selected" image_unselected="Tool_Face" layout="topleft" left_pad="20" @@ -118,7 +118,7 @@ height="20" image_disabled="Tool_Create" image_disabled_selected="Tool_Create" - image_selected="Tool_Create" + image_selected="Tool_Create_Selected" image_unselected="Tool_Create" layout="topleft" left_pad="20" @@ -134,7 +134,7 @@ height="20" image_disabled="Tool_Dozer" image_disabled_selected="Tool_Dozer" - image_selected="Tool_Dozer" + image_selected="Tool_Dozer_Selected" image_unselected="Tool_Dozer" layout="topleft" left_pad="20" @@ -344,7 +344,7 @@ height="20" image_disabled="Object_Cube" image_disabled_selected="Object_Cube" - image_selected="Object_Cube" + image_selected="Object_Cube_Selected" image_unselected="Object_Cube" layout="topleft" left="4" @@ -357,7 +357,7 @@ height="20" image_disabled="Object_Prism" image_disabled_selected="Object_Prism" - image_selected="Object_Prism" + image_selected="Object_Prism_Selected" image_unselected="Object_Prism" layout="topleft" left_delta="26" @@ -370,7 +370,7 @@ height="20" image_disabled="Object_Pyramid" image_disabled_selected="Object_Pyramid" - image_selected="Object_Pyramid" + image_selected="Object_Pyramid_Selected" image_unselected="Object_Pyramid" layout="topleft" left_delta="26" @@ -383,7 +383,7 @@ height="20" image_disabled="Object_Tetrahedron" image_disabled_selected="Object_Tetrahedron" - image_selected="Object_Tetrahedron" + image_selected="Object_Tetrahedron_Selected" image_unselected="Object_Tetrahedron" layout="topleft" left_delta="26" @@ -396,7 +396,7 @@ height="20" image_disabled="Object_Cylinder" image_disabled_selected="Object_Cylinder" - image_selected="Object_Cylinder" + image_selected="Object_Cylinder_Selected" image_unselected="Object_Cylinder" layout="topleft" left_delta="26" @@ -409,7 +409,7 @@ height="20" image_disabled="Object_Hemi_Cylinder" image_disabled_selected="Object_Hemi_Cylinder" - image_selected="Object_Hemi_Cylinder" + image_selected="Object_Hemi_Cylinder_Selected" image_unselected="Object_Hemi_Cylinder" layout="topleft" left_delta="26" @@ -422,7 +422,7 @@ height="20" image_disabled="Object_Cone" image_disabled_selected="Object_Cone" - image_selected="Object_Cone" + image_selected="Object_Cone_Selected" image_unselected="Object_Cone" layout="topleft" left_delta="26" @@ -435,7 +435,7 @@ height="20" image_disabled="Object_Hemi_Cone" image_disabled_selected="Object_Hemi_Cone" - image_selected="Object_Hemi_Cone" + image_selected="Object_Hemi_Cone_Selected" image_unselected="Object_Hemi_Cone" layout="topleft" left_delta="26" @@ -448,7 +448,7 @@ height="20" image_disabled="Object_Sphere" image_disabled_selected="Object_Sphere" - image_selected="Object_Sphere" + image_selected="Object_Sphere_Selected" image_unselected="Object_Sphere" layout="topleft" left_delta="26" @@ -461,7 +461,7 @@ height="20" image_disabled="Object_Hemi_Sphere" image_disabled_selected="Object_Hemi_Sphere" - image_selected="Object_Hemi_Sphere" + image_selected="Object_Hemi_Sphere_Selected" image_unselected="Object_Hemi_Sphere" layout="topleft" left_delta="26" @@ -474,7 +474,7 @@ height="20" image_disabled="Object_Torus" image_disabled_selected="Object_Torus" - image_selected="Object_Torus" + image_selected="Object_Torus_Selected" image_unselected="Object_Torus" layout="topleft" left="4" @@ -487,7 +487,7 @@ height="20" image_disabled="Object_Tube" image_disabled_selected="Object_Tube" - image_selected="Object_Tube" + image_selected="Object_Tube_Selected" image_unselected="Object_Tube" layout="topleft" left_delta="26" @@ -500,7 +500,7 @@ height="20" image_disabled="Object_Ring" image_disabled_selected="Object_Ring" - image_selected="Object_Ring" + image_selected="Object_Ring_Selected" image_unselected="Object_Ring" layout="topleft" left_delta="26" @@ -513,7 +513,7 @@ height="20" image_disabled="Object_Tree" image_disabled_selected="Object_Tree" - image_selected="Object_Tree" + image_selected="Object_Tree_Selected" image_unselected="Object_Tree" layout="topleft" left_delta="26" @@ -526,8 +526,9 @@ height="20" image_disabled="Object_Grass" image_disabled_selected="Object_Grass" - image_selected="Object_Grass" + image_selected="Object_Grass_Selected" image_unselected="Object_Grass" + image_overlay_color="Red" layout="topleft" left_delta="26" name="ToolGrass" diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml index 805ffbae66..d03a7e3d41 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml @@ -78,6 +78,9 @@ name="Pay"> <menu_item_call.on_click function="Avatar.Pay" /> + <menu_item_call.on_enable + function="ParticipantList.EnableItem" + parameter="can_pay" /> </menu_item_call> <menu_item_separator layout="topleft" /> diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index 677bdbc3d2..31719aad20 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -18,6 +18,10 @@ name="type_pg"> General Content </panel.string> + <panel.string + name="l$_price"> + L$[PRICE] + </panel.string> <button follows="top|right" height="23" @@ -71,8 +75,11 @@ name="classified_snapshot" top="20" width="290" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top|right" + h_pad="0" height="35" width="290" layout="topleft" @@ -81,35 +88,53 @@ left="10" top_pad="10" name="classified_name" + read_only="true" text_color="white" + v_pad="0" value="[name]" use_ellipses="true" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top" + h_pad="0" height="25" layout="topleft" left="10" name="classified_location" + read_only="true" width="290" word_wrap="true" + v_pad="0" value="[loading...]" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top|right" + h_pad="0" height="18" layout="topleft" left="10" name="content_type" + read_only="true" width="290" top_pad="5" + v_pad="0" value="[content type]" /> - <text + <text_editor + allow_html="true" + allow_scroll="false" + bg_visible="false" follows="left|top|right" + h_pad="0" height="18" layout="topleft" left="10" name="category" + read_only="true" width="290" top_pad="5" + v_pad="0" value="[category]" /> <check_box enabled="false" @@ -119,26 +144,37 @@ left="10" name="auto_renew" top_pad="5" + v_pad="0" width="290" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top" + h_pad="0" halign="left" height="16" layout="topleft" left="10" name="price_for_listing" + read_only="true" top_pad="5" tool_tip="Price for listing." - width="105"> - L$[PRICE] - </text> - <text + v_pad="0" + width="105" /> + <text_editor + allow_html="true" + allow_scroll="false" + bg_visible="false" follows="left|top|right" + h_pad="0" height="200" layout="topleft" left="10" + max_length="1023" name="classified_desc" + read_only="true" width="290" + v_pad="0" value="[description]" word_wrap="true" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml index 8f7750628e..2a2199fc87 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -255,13 +255,18 @@ top_pad="10" value="My Account:" width="100" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top|right" - height="15" + h_pad="0" + height="28" layout="topleft" left="10" name="acc_status_text" + read_only="true" top_pad="5" + v_pad="0" value="Resident. No payment info on file." width="200" word_wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml index a0734d3dca..d519569543 100644 --- a/indra/newview/skins/default/xui/en/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml @@ -206,13 +206,18 @@ top_pad="10" value="Resident Since:" width="300" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top" + h_pad="0" height="15" layout="topleft" left="10" name="register_date" + read_only="true" translate="false" + v_pad="0" value="05/31/2376" width="300" word_wrap="true" /> @@ -238,19 +243,24 @@ top_delta="0" value="Go to Dashboard" width="100"/> --> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top" + h_pad="0" height="28" layout="topleft" left="10" name="acc_status_text" + read_only="true" top_pad="0" translate="false" + v_pad="0" width="300" word_wrap="true"> Resident. No payment info on file. Linden. - </text> + </text_editor> <text follows="left|top" font.style="BOLD" diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 5fe5db892a..02eddc9212 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -39,8 +39,9 @@ layout="topleft" name="navigation_panel" width="600"> - <button + <pull_button follows="left|top" + direction="down" height="23" image_overlay="Arrow_Left_Off" layout="topleft" @@ -49,8 +50,9 @@ tool_tip="Go back to previous location" top="2" width="31" /> - <button + <pull_button follows="left|top" + direction="down" height="23" image_overlay="Arrow_Right_Off" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index 7489988722..375f369ba7 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -61,8 +61,11 @@ name="pick_snapshot" top="20" width="280" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top|right" + h_pad="0" height="35" width="280" layout="topleft" @@ -71,17 +74,24 @@ left="10" top_pad="10" name="pick_name" + read_only="true" text_color="white" + v_pad="0" value="[name]" use_ellipses="true" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top|right" + h_pad="0" height="25" layout="topleft" left="10" name="pick_location" + read_only="true" width="280" word_wrap="true" + v_pad="0" value="[loading...]" /> <text_editor bg_readonly_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 9bfd8b91d8..c4e4b9aa9b 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -17,12 +17,13 @@ background_visible="true" name="teleport_history_tab_title" value="TELEPORT HISTORY" /> <filter_editor + text_pad_left="14" follows="left|top|right" - font="SansSerif" + font="SansSerifSmall" height="23" layout="topleft" left="15" - label="Filter Places" + label="Filter My Places" max_length="300" name="Filter" top="3" diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 27461571da..351df22042 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -173,8 +173,7 @@ value="http://librarianavengers.org" width="300" word_wrap="false" - use_ellipses="true" - /> + use_ellipses="true" /> <text follows="left|top" font.style="BOLD" @@ -186,13 +185,18 @@ top_pad="10" value="Resident Since:" width="300" /> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top" + h_pad="0" height="15" layout="topleft" left="10" name="register_date" + read_only="true" translate="false" + v_pad="0" value="05/31/2376" width="300" word_wrap="true" /> @@ -218,19 +222,24 @@ top_delta="0" value="Go to Dashboard" width="100"/> --> - <text + <text_editor + allow_scroll="false" + bg_visible="false" follows="left|top" + h_pad="0" height="28" layout="topleft" left="10" name="acc_status_text" + read_only="true" top_pad="0" translate="false" + v_pad="0" width="300" word_wrap="true"> Resident. No payment info on file. Linden. - </text> + </text_editor> <text follows="left|top" font.style="BOLD" @@ -306,7 +315,7 @@ name="add_friend" tool_tip="Offer friendship to the Resident" top="5" - width="81" /> + width="80" /> <button follows="bottom|left" height="23" @@ -316,7 +325,7 @@ tool_tip="Open instant message session" top="5" left_pad="3" - width="45" /> + width="39" /> <button follows="bottom|left" height="23" @@ -326,7 +335,7 @@ tool_tip="Call this Resident" left_pad="3" top="5" - width="46" /> + width="43" /> <button enabled="false" follows="bottom|left" @@ -337,7 +346,7 @@ tool_tip="Show the Resident on the map" top="5" left_pad="3" - width="46" /> + width="41" /> <button follows="bottom|left" height="23" @@ -347,8 +356,8 @@ tool_tip="Offer teleport" left_pad="3" top="5" - width="78" /> - <!-- <button + width="69" /> + <button follows="bottom|right" height="23" label="▼" @@ -357,8 +366,8 @@ tool_tip="Pay money to or share inventory with the Resident" right="-1" top="5" - left_pad="3" - width="23" />--> + left_pad="3" + width="23" /> </layout_panel> <layout_panel follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml index f59c46b2f5..d9b6387f0d 100644 --- a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml +++ b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml @@ -2,10 +2,13 @@ <expandable_text max_height="300" > <textbox - more_label="More" + allow_html="true" + allow_scroll="true" + bg_visible="false" + more_label="More" follows="left|top|right" name="text" - allow_scroll="true" + read_only="true" use_ellipses="true" word_wrap="true" tab_stop="true" @@ -16,4 +19,4 @@ name="scroll" follows="all" /> -</expandable_text>
\ No newline at end of file +</expandable_text> diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index 70a58b8e03..2163660206 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -96,7 +96,7 @@ name="damage_icon" width="14" height="13" - top="21" + top="19" left="2" follows="right|top" image_name="Parcel_Damage_Dark" @@ -106,7 +106,7 @@ name="damage_text" width="35" height="18" - top="16" + top="17" follows="right|top" halign="right" font="SansSerifSmall" |