diff options
author | angela <angela@lindenlab.com> | 2010-02-03 13:56:39 +0800 |
---|---|---|
committer | angela <angela@lindenlab.com> | 2010-02-03 13:56:39 +0800 |
commit | 460ec67b97bc210c0a03483dd0b754e92fabe806 (patch) | |
tree | 90bd49da9c7e23e6b90ebf04b8fcc9847b4f414e | |
parent | 1094fa28c618370af9a95cf823cbd9287c92dd24 (diff) | |
parent | 86923afd27d76734cf1274fa788928230c232a4d (diff) |
resolve merge in llsidepanelinventory.cpp
85 files changed, 1637 insertions, 945 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..75ca6d8895 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -185,7 +185,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mWriteableBgColor(p.bg_writeable_color), mReadOnlyBgColor(p.bg_readonly_color), mFocusBgColor(p.bg_focus_color), - mReflowNeeded(FALSE), + mReflowIndex(S32_MAX), mCursorPos( 0 ), mScrollNeeded(FALSE), mDesiredXPixel(-1), @@ -660,7 +660,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s } onValueChange(pos, pos + insert_len); - needsReflow(); + needsReflow(pos); return insert_len; } @@ -720,7 +720,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length) createDefaultSegment(); onValueChange(pos, pos); - needsReflow(); + needsReflow(pos); return -length; // This will be wrong if someone calls removeStringNoUndo with an excessive length } @@ -736,7 +736,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc) getViewModel()->setDisplay(text); onValueChange(pos, pos + 1); - needsReflow(); + needsReflow(pos); return 1; } @@ -762,15 +762,18 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) } segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart()); + S32 reflow_start_index = 0; if (cur_seg_iter == mSegments.end()) { mSegments.insert(segment_to_insert); segment_to_insert->linkToDocument(this); + reflow_start_index = segment_to_insert->getStart(); } else { LLTextSegmentPtr cur_segmentp = *cur_seg_iter; + reflow_start_index = cur_segmentp->getStart(); if (cur_segmentp->getStart() < segment_to_insert->getStart()) { S32 old_segment_end = cur_segmentp->getEnd(); @@ -829,7 +832,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) } // layout potentially changed - needsReflow(); + needsReflow(reflow_start_index); } BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) @@ -1024,6 +1027,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()); @@ -1074,15 +1087,16 @@ S32 LLTextBase::getLeftOffset(S32 width) static LLFastTimer::DeclareTimer FTM_TEXT_REFLOW ("Text Reflow"); -void LLTextBase::reflow(S32 start_index) +void LLTextBase::reflow() { LLFastTimer ft(FTM_TEXT_REFLOW); updateSegments(); - while(mReflowNeeded) + while(mReflowIndex < S32_MAX) { - mReflowNeeded = false; + S32 start_index = mReflowIndex; + mReflowIndex = S32_MAX; // shrink document to minimum size (visible portion of text widget) // to force inlined widgets with follows set to shrink @@ -1609,6 +1623,12 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c } } +void LLTextBase::needsReflow(S32 index) +{ + lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl; + mReflowIndex = llmin(mReflowIndex, index); +} + void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params) { if (new_text.empty()) return; @@ -2250,7 +2270,7 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e LLUIImagePtr image = mStyle->getImage(); if (image.notNull()) { - mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor)); + mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor, start)); } } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index b5c7fab67a..3dda6f4cc8 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; @@ -149,7 +150,7 @@ public: void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params()); // force reflow of text - void needsReflow() { mReflowNeeded = TRUE; } + void needsReflow(S32 index = 0); S32 getLength() const { return getWText().length(); } S32 getLineCount() const { return mLineInfoList.size(); } @@ -291,7 +292,7 @@ protected: S32 getFirstVisibleLine() const; std::pair<S32, S32> getVisibleLines(bool fully_visible = false); S32 getLeftOffset(S32 width); - void reflow(S32 start_index = 0); + void reflow(); // cursor void updateCursorXPos(); @@ -361,7 +362,7 @@ protected: class LLScrollContainer* mScroller; // transient state - bool mReflowNeeded; // need to reflow text because of change to text contents or display region + S32 mReflowIndex; // index at which to start reflow. S32_MAX indicates no reflow needed. bool mScrollNeeded; // need to change scroll region because of change to cursor position S32 mScrollIndex; // index of first character to keep visible in scroll region diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index e76fee9f17..7a19b7427c 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1285,8 +1285,6 @@ void LLTextEditor::cut() gClipboard.copyFromSubstring( getWText(), left_pos, length, mSourceID ); deleteSelection( FALSE ); - needsReflow(); - onKeyStroke(); } @@ -1391,8 +1389,6 @@ void LLTextEditor::pasteHelper(bool is_primary) setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE, LLTextSegmentPtr())); deselect(); - needsReflow(); - onKeyStroke(); } @@ -1787,8 +1783,6 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask ) if(text_may_have_changed) { - needsReflow(); - onKeyStroke(); } needsScroll(); @@ -1831,8 +1825,6 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char) // Most keystrokes will make the selection box go away, but not all will. deselect(); - needsReflow(); - onKeyStroke(); } @@ -1891,8 +1883,6 @@ void LLTextEditor::doDelete() } onKeyStroke(); - - needsReflow(); } //---------------------------------------------------------------------------- @@ -1935,8 +1925,6 @@ void LLTextEditor::undo() setCursorPos(pos); - needsReflow(); - onKeyStroke(); } @@ -1979,8 +1967,6 @@ void LLTextEditor::redo() setCursorPos(pos); - needsReflow(); - onKeyStroke(); } @@ -2339,8 +2325,6 @@ void LLTextEditor::insertText(const std::string &new_text) setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE, LLTextSegmentPtr() )); - needsReflow(); - setEnabled( enabled ); } @@ -2363,8 +2347,6 @@ void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const LLTextSegmentPtr segment = new LLInlineViewSegment(params, old_length, old_length + widget_wide_text.size()); insert(getLength(), widget_wide_text, FALSE, segment); - needsReflow(); - // Set the cursor and scroll position if( selection_start != selection_end ) { @@ -2389,52 +2371,6 @@ void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const } } - -void LLTextEditor::replaceUrlLabel(const std::string &url, - const std::string &label) -{ - // get the full (wide) text for the editor so we can change it - LLWString text = getWText(); - LLWString wlabel = utf8str_to_wstring(label); - bool modified = false; - S32 seg_start = 0; - - // iterate through each segment looking for ones styled as links - segment_set_t::iterator it; - for (it = mSegments.begin(); it != mSegments.end(); ++it) - { - LLTextSegment *seg = *it; - LLStyleConstSP style = seg->getStyle(); - - // update segment start/end length in case we replaced text earlier - S32 seg_length = seg->getEnd() - seg->getStart(); - seg->setStart(seg_start); - seg->setEnd(seg_start + seg_length); - - // if we find a link with our Url, then replace the label - if (style->isLink() && style->getLinkHREF() == url) - { - S32 start = seg->getStart(); - S32 end = seg->getEnd(); - text = text.substr(0, start) + wlabel + text.substr(end, text.size() - end + 1); - seg->setEnd(start + wlabel.size()); - modified = true; - } - - // work out the character offset for the next segment - seg_start = seg->getEnd(); - } - - // update the editor with the new (wide) text string - if (modified) - { - getViewModel()->setDisplay(text); - deselect(); - setCursorPos(mCursorPos); - needsReflow(); - } -} - void LLTextEditor::removeTextFromEnd(S32 num_chars) { if (num_chars <= 0) return; @@ -2446,7 +2382,6 @@ void LLTextEditor::removeTextFromEnd(S32 num_chars) mSelectionStart = llclamp(mSelectionStart, 0, len); mSelectionEnd = llclamp(mSelectionEnd, 0, len); - needsReflow(); needsScroll(); } @@ -2505,8 +2440,6 @@ BOOL LLTextEditor::tryToRevertToPristineState() i--; } } - - needsReflow(); } return isPristine(); // TRUE => success @@ -2681,7 +2614,6 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length ) startOfDoc(); deselect(); - needsReflow(); return success; } @@ -2785,7 +2717,6 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string, mPreeditStandouts = preedit_standouts; - needsReflow(); setCursorPos(insert_preedit_at + caret_position); // Update of the preedit should be caused by some key strokes. diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 043dda8fa6..a136f9ccce 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -149,7 +149,6 @@ public: void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); - void replaceUrlLabel(const std::string &url, const std::string &label); // Undo/redo stack void blockUndo(); 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/lldrawable.h b/indra/newview/lldrawable.h index 5a10b688da..651dabff9e 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -44,7 +44,6 @@ #include "llquaternion.h" #include "xform.h" #include "llmemtype.h" -#include "llprimitive.h" #include "lldarray.h" #include "llviewerobject.h" #include "llrect.h" 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/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 60f150bd96..904655cdc8 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -86,38 +86,40 @@ const F32 BASE_ANIM_TIME_OFFSET = 5.f; std::string STATUS[] = { - "E_ST_OK", - "E_ST_EOF", - "E_ST_NO_CONSTRAINT", - "E_ST_NO_FILE", -"E_ST_NO_HIER", -"E_ST_NO_JOINT", -"E_ST_NO_NAME", -"E_ST_NO_OFFSET", -"E_ST_NO_CHANNELS", -"E_ST_NO_ROTATION", -"E_ST_NO_AXIS", -"E_ST_NO_MOTION", -"E_ST_NO_FRAMES", -"E_ST_NO_FRAME_TIME", -"E_ST_NO_POS", -"E_ST_NO_ROT", -"E_ST_NO_XLT_FILE", -"E_ST_NO_XLT_HEADER", -"E_ST_NO_XLT_NAME", -"E_ST_NO_XLT_IGNORE", -"E_ST_NO_XLT_RELATIVE", -"E_ST_NO_XLT_OUTNAME", -"E_ST_NO_XLT_MATRIX", -"E_ST_NO_XLT_MERGECHILD", -"E_ST_NO_XLT_MERGEPARENT", -"E_ST_NO_XLT_PRIORITY", -"E_ST_NO_XLT_LOOP", -"E_ST_NO_XLT_EASEIN", -"E_ST_NO_XLT_EASEOUT", -"E_ST_NO_XLT_HAND", -"E_ST_NO_XLT_EMOTE", + "E_ST_OK", + "E_ST_EOF", + "E_ST_NO_CONSTRAINT", + "E_ST_NO_FILE", + "E_ST_NO_HIER", + "E_ST_NO_JOINT", + "E_ST_NO_NAME", + "E_ST_NO_OFFSET", + "E_ST_NO_CHANNELS", + "E_ST_NO_ROTATION", + "E_ST_NO_AXIS", + "E_ST_NO_MOTION", + "E_ST_NO_FRAMES", + "E_ST_NO_FRAME_TIME", + "E_ST_NO_POS", + "E_ST_NO_ROT", + "E_ST_NO_XLT_FILE", + "E_ST_NO_XLT_HEADER", + "E_ST_NO_XLT_NAME", + "E_ST_NO_XLT_IGNORE", + "E_ST_NO_XLT_RELATIVE", + "E_ST_NO_XLT_OUTNAME", + "E_ST_NO_XLT_MATRIX", + "E_ST_NO_XLT_MERGECHILD", + "E_ST_NO_XLT_MERGEPARENT", + "E_ST_NO_XLT_PRIORITY", + "E_ST_NO_XLT_LOOP", + "E_ST_NO_XLT_EASEIN", + "E_ST_NO_XLT_EASEOUT", + "E_ST_NO_XLT_HAND", + "E_ST_NO_XLT_EMOTE", + "E_ST_BAD_ROOT" }; + //----------------------------------------------------------------------------- // LLFloaterAnimPreview() //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 0ad283d7c6..8cd63deebe 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -427,8 +427,26 @@ BOOL LLPanelLandGeneral::postBuild() mBtnBuyLand = getChild<LLButton>("Buy Land..."); mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND); - mBtnScriptLimits = getChild<LLButton>("Scripts..."); - mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this); + // note: on region change this will not be re checked, should not matter on Agni as + // 99% of the time all regions will return the same caps. In case of an erroneous setting + // to enabled the floater will just throw an error when trying to get it's cap + std::string url = gAgent.getRegion()->getCapability("LandResources"); + if (!url.empty()) + { + mBtnScriptLimits = getChild<LLButton>("Scripts..."); + if(mBtnScriptLimits) + { + mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this); + } + } + else + { + mBtnScriptLimits = getChild<LLButton>("Scripts..."); + if(mBtnScriptLimits) + { + mBtnScriptLimits->setVisible(false); + } + } mBtnBuyGroupLand = getChild<LLButton>("Buy For Group..."); mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND); diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 8875e35821..4194416a01 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -59,10 +59,30 @@ /// LLFloaterScriptLimits ///---------------------------------------------------------------------------- -// due to server side bugs the full summary display is not possible -// until they are fixed this define creates a simple version of the -// summary which only shows available & correct information -#define USE_SIMPLE_SUMMARY +// debug switches, won't work in release +#ifndef LL_RELEASE_FOR_DOWNLOAD + +// dump responder replies to llinfos for debugging +//#define DUMP_REPLIES_TO_LLINFOS + +#ifdef DUMP_REPLIES_TO_LLINFOS +#include "llsdserialize.h" +#include "llwindow.h" +#endif + +// use fake LLSD responses to check the viewer side is working correctly +// I'm syncing this with the server side efforts so hopfully we can keep +// the to-ing and fro-ing between the two teams to a minimum +//#define USE_FAKE_RESPONSES + +#ifdef USE_FAKE_RESPONSES +const S32 FAKE_NUMBER_OF_URLS = 329; +const S32 FAKE_AVAILABLE_URLS = 731; +const S32 FAKE_AMOUNT_OF_MEMORY = 66741; +const S32 FAKE_AVAILABLE_MEMORY = 895577; +#endif + +#endif const S32 SIZE_OF_ONE_KB = 1024; @@ -87,32 +107,41 @@ BOOL LLFloaterScriptLimits::postBuild() } mTab = getChild<LLTabContainer>("scriptlimits_panels"); + + if(!mTab) + { + llinfos << "Error! couldn't get scriptlimits_panels, aborting Script Information setup" << llendl; + return FALSE; + } // contruct the panels - LLPanelScriptLimitsRegionMemory* panel_memory; - panel_memory = new LLPanelScriptLimitsRegionMemory; - mInfoPanels.push_back(panel_memory); + std::string land_url = gAgent.getRegion()->getCapability("LandResources"); + if (!land_url.empty()) + { + LLPanelScriptLimitsRegionMemory* panel_memory; + panel_memory = new LLPanelScriptLimitsRegionMemory; + mInfoPanels.push_back(panel_memory); + LLUICtrlFactory::getInstance()->buildPanel(panel_memory, "panel_script_limits_region_memory.xml"); + mTab->addTabPanel(panel_memory); + } - LLUICtrlFactory::getInstance()->buildPanel(panel_memory, "panel_script_limits_region_memory.xml"); - mTab->addTabPanel(panel_memory); - - LLPanelScriptLimitsRegionURLs* panel_urls = new LLPanelScriptLimitsRegionURLs; - mInfoPanels.push_back(panel_urls); - LLUICtrlFactory::getInstance()->buildPanel(panel_urls, "panel_script_limits_region_urls.xml"); - mTab->addTabPanel(panel_urls); - - LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment; - mInfoPanels.push_back(panel_attachments); - LLUICtrlFactory::getInstance()->buildPanel(panel_attachments, "panel_script_limits_my_avatar.xml"); - mTab->addTabPanel(panel_attachments); - - if(selectParcelPanel) + std::string attachment_url = gAgent.getRegion()->getCapability("AttachmentResources"); + if (!attachment_url.empty()) + { + LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment; + mInfoPanels.push_back(panel_attachments); + LLUICtrlFactory::getInstance()->buildPanel(panel_attachments, "panel_script_limits_my_avatar.xml"); + mTab->addTabPanel(panel_attachments); + } + + if(mInfoPanels.size() > 0) { mTab->selectTab(0); } - else + + if(!selectParcelPanel && (mInfoPanels.size() > 1)) { - mTab->selectTab(2); + mTab->selectTab(1); } return TRUE; @@ -160,6 +189,20 @@ void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr) void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content) { + //we don't need to test with a fake respose here (shouldn't anyway) + +#ifdef DUMP_REPLIES_TO_LLINFOS + + LLSDNotationStreamer notation_streamer(content); + std::ostringstream nice_llsd; + nice_llsd << notation_streamer; + + OSMessageBox(nice_llsd.str(), "main cap response:", 0); + + llinfos << "main cap response:" << content << llendl; + +#endif + // at this point we have an llsd which should contain ether one or two urls to the services we want. // first we look for the details service: if(content.has("ScriptResourceDetails")) @@ -173,24 +216,6 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content) { llinfos << "Failed to get llfloaterscriptlimits instance" << llendl; } - else - { - -// temp - only show info if we get details - there's nothing to show if not until the sim gets fixed -#ifdef USE_SIMPLE_SUMMARY - - LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); - std::string msg = LLTrans::getString("ScriptLimitsRequestDontOwnParcel"); - panel_memory->childSetValue("loading_text", LLSD(msg)); - LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); - panel_urls->childSetValue("loading_text", LLSD(msg)); - - // intentional early out as we dont want the resource summary if we are using the "simple summary" - // and the details are missing - return; -#endif - } } // then the summary service: @@ -205,8 +230,61 @@ void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& llinfos << "Error from responder " << reason << llendl; } -void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content) +void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) { +#ifdef USE_FAKE_RESPONSES + + LLSD fake_content; + LLSD summary = LLSD::emptyMap(); + LLSD available = LLSD::emptyArray(); + LLSD available_urls = LLSD::emptyMap(); + LLSD available_memory = LLSD::emptyMap(); + LLSD used = LLSD::emptyArray(); + LLSD used_urls = LLSD::emptyMap(); + LLSD used_memory = LLSD::emptyMap(); + + used_urls["type"] = "urls"; + used_urls["amount"] = FAKE_NUMBER_OF_URLS; + available_urls["type"] = "urls"; + available_urls["amount"] = FAKE_AVAILABLE_URLS; + used_memory["type"] = "memory"; + used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY; + available_memory["type"] = "memory"; + available_memory["amount"] = FAKE_AVAILABLE_MEMORY; + +//summary response:{'summary':{'available':[{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'},{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'}],'used':[{'amount':i329,'type':'urls'},{'amount':i66741,'type':'memory'}]}} + + used.append(used_urls); + used.append(used_memory); + available.append(available_urls); + available.append(available_memory); + + summary["available"] = available; + summary["used"] = used; + + fake_content["summary"] = summary; + + const LLSD& content = fake_content; + +#else + + const LLSD& content = content_ref; + +#endif + + +#ifdef DUMP_REPLIES_TO_LLINFOS + + LLSDNotationStreamer notation_streamer(content); + std::ostringstream nice_llsd; + nice_llsd << notation_streamer; + + OSMessageBox(nice_llsd.str(), "summary response:", 0); + + llinfos << "summary response:" << *content << llendl; + +#endif + LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); if(!instance) { @@ -217,8 +295,6 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content) LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); panel_memory->setRegionSummary(content); - LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); - panel_urls->setRegionSummary(content); } } @@ -227,8 +303,82 @@ void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::strin llinfos << "Error from responder " << reason << llendl; } -void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content) +void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref) { +#ifdef USE_FAKE_RESPONSES +/* +Updated detail service, ** denotes field added: + +result (map) ++-parcels (array of maps) + +-id (uuid) + +-local_id (S32)** + +-name (string) + +-owner_id (uuid) (in ERS as owner, but owner_id in code) + +-objects (array of maps) + +-id (uuid) + +-name (string) + +-owner_id (uuid) (in ERS as owner, in code as owner_id) + +-owner_name (sting)** + +-location (map)** + +-x (float) + +-y (float) + +-z (float) + +-resources (map) (this is wrong in the ERS but right in code) + +-type (string) + +-amount (int) +*/ + LLSD fake_content; + LLSD resource = LLSD::emptyMap(); + LLSD location = LLSD::emptyMap(); + LLSD object = LLSD::emptyMap(); + LLSD objects = LLSD::emptyArray(); + LLSD parcel = LLSD::emptyMap(); + LLSD parcels = LLSD::emptyArray(); + + resource["urls"] = FAKE_NUMBER_OF_URLS; + resource["memory"] = FAKE_AMOUNT_OF_MEMORY; + + location["x"] = 128.0f; + location["y"] = 128.0f; + location["z"] = 0.0f; + + object["id"] = LLUUID("d574a375-0c6c-fe3d-5733-da669465afc7"); + object["name"] = "Gabs fake Object!"; + object["owner_id"] = LLUUID("8dbf2d41-69a0-4e5e-9787-0c9d297bc570"); + object["owner_name"] = "Gabs Linden"; + object["location"] = location; + object["resources"] = resource; + + objects.append(object); + + parcel["id"] = LLUUID("da05fb28-0d20-e593-2728-bddb42dd0160"); + parcel["local_id"] = 42; + parcel["name"] = "Gabriel Linden\'s Sub Plot"; + parcel["objects"] = objects; + parcels.append(parcel); + + fake_content["parcels"] = parcels; + const LLSD& content = fake_content; + +#else + + const LLSD& content = content_ref; + +#endif + +#ifdef DUMP_REPLIES_TO_LLINFOS + + LLSDNotationStreamer notation_streamer(content); + std::ostringstream nice_llsd; + nice_llsd << notation_streamer; + + OSMessageBox(nice_llsd.str(), "details response:", 0); + + llinfos << "details response:" << content << llendl; + +#endif + LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); if(!instance) @@ -238,11 +388,22 @@ void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content) else { LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); - panel_memory->setRegionDetails(content); - - LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); - panel_urls->setRegionDetails(content); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + if(panel_memory) + { + panel_memory->setRegionDetails(content); + } + else + { + llinfos << "Failed to get scriptlimits memory panel" << llendl; + } + } + else + { + llinfos << "Failed to get scriptlimits_panels" << llendl; + } } } @@ -251,8 +412,61 @@ void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::strin llinfos << "Error from responder " << reason << llendl; } -void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content) +void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref) { + +#ifdef USE_FAKE_RESPONSES + + // just add the summary, as that's all I'm testing currently! + LLSD fake_content = LLSD::emptyMap(); + LLSD summary = LLSD::emptyMap(); + LLSD available = LLSD::emptyArray(); + LLSD available_urls = LLSD::emptyMap(); + LLSD available_memory = LLSD::emptyMap(); + LLSD used = LLSD::emptyArray(); + LLSD used_urls = LLSD::emptyMap(); + LLSD used_memory = LLSD::emptyMap(); + + used_urls["type"] = "urls"; + used_urls["amount"] = FAKE_NUMBER_OF_URLS; + available_urls["type"] = "urls"; + available_urls["amount"] = FAKE_AVAILABLE_URLS; + used_memory["type"] = "memory"; + used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY; + available_memory["type"] = "memory"; + available_memory["amount"] = FAKE_AVAILABLE_MEMORY; + + used.append(used_urls); + used.append(used_memory); + available.append(available_urls); + available.append(available_memory); + + summary["available"] = available; + summary["used"] = used; + + fake_content["summary"] = summary; + fake_content["attachments"] = content_ref["attachments"]; + + const LLSD& content = fake_content; + +#else + + const LLSD& content = content_ref; + +#endif + +#ifdef DUMP_REPLIES_TO_LLINFOS + + LLSDNotationStreamer notation_streamer(content); + std::ostringstream nice_llsd; + nice_llsd << notation_streamer; + + OSMessageBox(nice_llsd.str(), "attachment response:", 0); + + llinfos << "attachment response:" << content << llendl; + +#endif + LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); if(!instance) @@ -262,8 +476,22 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content) else { LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel"); - panel->setAttachmentDetails(content); + if(tab) + { + LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel"); + if(panel) + { + panel->setAttachmentDetails(content); + } + else + { + llinfos << "Failed to get script_limits_my_avatar_panel" << llendl; + } + } + else + { + llinfos << "Failed to get scriptlimits_panels" << llendl; + } } } @@ -309,7 +537,7 @@ void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parc { std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); childSetValue("loading_text", LLSD(msg_waiting)); - } + } } void LLPanelScriptLimitsRegionMemory::setParcelID(const LLUUID& parcel_id) @@ -341,6 +569,11 @@ void LLPanelScriptLimitsRegionMemory::onNameCache( std::string name = first_name + " " + last_name; LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); + if(!list) + { + return; + } + std::vector<LLSD>::iterator id_itor; for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) { @@ -351,33 +584,8 @@ void LLPanelScriptLimitsRegionMemory::onNameCache( if(item) { - item->getColumn(2)->setValue(LLSD(name)); - element["columns"][2]["value"] = name; - } - } - } - - // fill in the url's tab if needed, all urls must have memory so we can do it all here - LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); - if(instance) - { - LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); - - LLScrollListCtrl *list = panel->getChild<LLScrollListCtrl>("scripts_list"); - std::vector<LLSD>::iterator id_itor; - for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) - { - LLSD element = *id_itor; - if(element["owner_id"].asUUID() == id) - { - LLScrollListItem* item = list->getItem(element["id"].asUUID()); - - if(item) - { - item->getColumn(2)->setValue(LLSD(name)); - element["columns"][2]["value"] = name; - } + item->getColumn(3)->setValue(LLSD(name)); + element["columns"][3]["value"] = name; } } } @@ -386,6 +594,12 @@ void LLPanelScriptLimitsRegionMemory::onNameCache( void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) { LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); + + if(!list) + { + llinfos << "Error getting the scripts_list control" << llendl; + return; + } S32 number_parcels = content["parcels"].size(); @@ -394,130 +608,197 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) std::string msg_parcels = LLTrans::getString("ScriptLimitsParcelsOwned", args_parcels); childSetValue("parcels_listed", LLSD(msg_parcels)); - S32 total_objects = 0; - S32 total_size = 0; - std::vector<LLUUID> names_requested; + // This makes the assumption that all objects will have the same set + // of attributes, ie they will all have, or none will have locations + // This is a pretty safe assumption as it's reliant on server version. + bool has_locations = false; + bool has_local_ids = false; + for(S32 i = 0; i < number_parcels; i++) { std::string parcel_name = content["parcels"][i]["name"].asString(); LLUUID parcel_id = content["parcels"][i]["id"].asUUID(); S32 number_objects = content["parcels"][i]["objects"].size(); + + S32 local_id = 0; + if(content["parcels"][i].has("local_id")) + { + // if any locations are found flag that we can use them and turn on the highlight button + has_local_ids = true; + local_id = content["parcels"][i]["local_id"].asInteger(); + } + for(S32 j = 0; j < number_objects; j++) { S32 size = content["parcels"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB; - total_size += size; + + S32 urls = content["parcels"][i]["objects"][j]["resources"]["urls"].asInteger(); std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString(); LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID(); LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID(); - + + F32 location_x = 0.0f; + F32 location_y = 0.0f; + F32 location_z = 0.0f; + + if(content["parcels"][i]["objects"][j].has("location")) + { + // if any locations are found flag that we can use them and turn on the highlight button + LLVector3 vec = ll_vector3_from_sd(content["parcels"][i]["objects"][j]["location"]); + has_locations = true; + location_x = vec.mV[0]; + location_y = vec.mV[1]; + location_z = vec.mV[2]; + } + std::string owner_buf; - - BOOL name_is_cached = gCacheName->getFullName(owner_id, owner_buf); - if(!name_is_cached) + + // in the future the server will give us owner names, so see if we're there yet: + if(content["parcels"][i]["objects"][j].has("owner_name")) + { + owner_buf = content["parcels"][i]["objects"][j]["owner_name"].asString(); + } + // ...and if not use the slightly more painful method of disovery: + else { - if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end()) + BOOL name_is_cached = gCacheName->getFullName(owner_id, owner_buf); + if(!name_is_cached) { - names_requested.push_back(owner_id); - gCacheName->get(owner_id, TRUE, - boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, - this, _1, _2, _3)); + if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end()) + { + names_requested.push_back(owner_id); + gCacheName->get(owner_id, TRUE, + boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, + this, _1, _2, _3)); + } } } LLSD element; element["id"] = task_id; - element["owner_id"] = owner_id; element["columns"][0]["column"] = "size"; element["columns"][0]["value"] = llformat("%d", size); element["columns"][0]["font"] = "SANSSERIF"; - element["columns"][1]["column"] = "name"; - element["columns"][1]["value"] = name_buf; + element["columns"][1]["column"] = "urls"; + element["columns"][1]["value"] = llformat("%d", urls); element["columns"][1]["font"] = "SANSSERIF"; - element["columns"][2]["column"] = "owner"; - element["columns"][2]["value"] = owner_buf; + element["columns"][2]["column"] = "name"; + element["columns"][2]["value"] = name_buf; element["columns"][2]["font"] = "SANSSERIF"; - element["columns"][3]["column"] = "location"; - element["columns"][3]["value"] = parcel_name; + element["columns"][3]["column"] = "owner"; + element["columns"][3]["value"] = owner_buf; element["columns"][3]["font"] = "SANSSERIF"; + element["columns"][4]["column"] = "parcel"; + element["columns"][4]["value"] = parcel_name; + element["columns"][4]["font"] = "SANSSERIF"; + element["columns"][5]["column"] = "location"; + if(has_locations) + { + element["columns"][5]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); + } + else + { + element["columns"][5]["value"] = ""; + } + element["columns"][5]["font"] = "SANSSERIF"; list->addElement(element, ADD_SORTED); + + element["owner_id"] = owner_id; + element["local_id"] = local_id; mObjectListItems.push_back(element); - total_objects++; } } - mParcelMemoryUsed =total_size; - mGotParcelMemoryUsed = TRUE; - populateParcelMemoryText(); -} + if (has_locations) + { + LLButton* btn = getChild<LLButton>("highlight_btn"); + if(btn) + { + btn->setVisible(true); + } + } -void LLPanelScriptLimitsRegionMemory::populateParcelMemoryText() -{ - if(mGotParcelMemoryUsed && mGotParcelMemoryMax) + if (has_local_ids) { -#ifdef USE_SIMPLE_SUMMARY - LLStringUtil::format_map_t args_parcel_memory; - args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); - std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsedSimple", args_parcel_memory); - childSetValue("memory_used", LLSD(msg_parcel_memory)); -#else - S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed; + LLButton* btn = getChild<LLButton>("return_btn"); + if(btn) + { + btn->setVisible(true); + } + } - LLStringUtil::format_map_t args_parcel_memory; - args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); - args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax); - args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available); - std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_parcel_memory); - childSetValue("memory_used", LLSD(msg_parcel_memory)); -#endif + // save the structure to make object return easier + mContent = content; - childSetValue("loading_text", LLSD(std::string(""))); - } + childSetValue("loading_text", LLSD(std::string(""))); } void LLPanelScriptLimitsRegionMemory::setRegionSummary(LLSD content) { - if(content["summary"]["available"][0]["type"].asString() == std::string("memory")) + if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) { - mParcelMemoryMax = content["summary"]["available"][0]["amount"].asInteger(); - mGotParcelMemoryMax = TRUE; + mParcelMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mParcelMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotParcelMemoryUsed = TRUE; } - else if(content["summary"]["available"][1]["type"].asString() == std::string("memory")) + else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) { - mParcelMemoryMax = content["summary"]["available"][1]["amount"].asInteger(); - mGotParcelMemoryMax = TRUE; + mParcelMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mParcelMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotParcelMemoryUsed = TRUE; } else { llinfos << "summary doesn't contain memory info" << llendl; return; } -/* - currently this is broken on the server, so we get this value from the details section - and update via populateParcelMemoryText() when both sets of information have been returned - - when the sim is fixed this should be used instead: - if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) + + if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) { - mParcelMemoryUsed = content["summary"]["used"][0]["amount"].asInteger(); - mGotParcelMemoryUsed = TRUE; + mParcelURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); + mParcelURLsMax = content["summary"]["available"][0]["amount"].asInteger(); + mGotParcelURLsUsed = TRUE; } - else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) + else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) { - mParcelMemoryUsed = content["summary"]["used"][1]["amount"].asInteger(); - mGotParcelMemoryUsed = TRUE; + mParcelURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); + mParcelURLsMax = content["summary"]["available"][1]["amount"].asInteger(); + mGotParcelURLsUsed = TRUE; } else { - //ERROR!!! + llinfos << "summary doesn't contain urls info" << llendl; return; - }*/ + } - populateParcelMemoryText(); + if((mParcelMemoryUsed >= 0) && (mParcelMemoryMax >= 0)) + { + S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed; + + LLStringUtil::format_map_t args_parcel_memory; + args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); + args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax); + args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available); + std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_parcel_memory); + childSetValue("memory_used", LLSD(msg_parcel_memory)); + } + + if((mParcelURLsUsed >= 0) && (mParcelURLsMax >= 0)) + { + S32 parcel_urls_available = mParcelURLsMax - mParcelURLsUsed; + + LLStringUtil::format_map_t args_parcel_urls; + args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed); + args_parcel_urls["[MAX]"] = llformat ("%d", mParcelURLsMax); + args_parcel_urls["[AVAILABLE]"] = llformat ("%d", parcel_urls_available); + std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_parcel_urls); + childSetValue("urls_used", LLSD(msg_parcel_urls)); + } } BOOL LLPanelScriptLimitsRegionMemory::postBuild() @@ -530,6 +811,10 @@ BOOL LLPanelScriptLimitsRegionMemory::postBuild() childSetValue("loading_text", LLSD(msg_waiting)); LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); + if(!list) + { + return FALSE; + } //set all columns to resizable mode even if some columns will be empty for(S32 column = 0; column < list->getNumColumns(); column++) @@ -548,18 +833,11 @@ BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain() LLFloaterLand* instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land"); if(!instance) { - //this isnt really an error... -// llinfos << "Failed to get about land instance" << llendl; -// std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); childSetValue("loading_text", LLSD(std::string(""))); //might have to do parent post build here //if not logic below could use early outs return FALSE; } - - LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); - LLParcel* parcel = instance->getCurrentSelectedParcel(); LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); @@ -575,7 +853,6 @@ BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain() { std::string msg_wrong_region = LLTrans::getString("ScriptLimitsRequestWrongRegion"); childSetValue("loading_text", LLSD(msg_wrong_region)); - panel_urls->childSetValue("loading_text", LLSD(msg_wrong_region)); return FALSE; } @@ -605,14 +882,12 @@ BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain() std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); childSetValue("loading_text", LLSD(msg_waiting)); - panel_urls->childSetValue("loading_text", LLSD(msg_waiting)); } } else { - std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestNoParcelSelected"); childSetValue("loading_text", LLSD(msg_waiting)); - panel_urls->childSetValue("loading_text", LLSD(msg_waiting)); } return LLPanelScriptLimitsInfo::postBuild(); @@ -629,10 +904,13 @@ void LLPanelScriptLimitsRegionMemory::clearList() mGotParcelMemoryUsed = FALSE; mGotParcelMemoryMax = FALSE; + mGotParcelURLsUsed = FALSE; + mGotParcelURLsMax = FALSE; LLStringUtil::format_map_t args_parcel_memory; std::string msg_empty_string(""); childSetValue("memory_used", LLSD(msg_empty_string)); + childSetValue("urls_used", LLSD(msg_empty_string)); childSetValue("parcels_listed", LLSD(msg_empty_string)); mObjectListItems.clear(); @@ -647,13 +925,16 @@ void LLPanelScriptLimitsRegionMemory::onClickRefresh(void* userdata) if(instance) { LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); - panel_memory->clearList(); - - LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); - panel_urls->clearList(); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + if(panel_memory) + { + panel_memory->clearList(); - panel_memory->StartRequestChain(); + panel_memory->StartRequestChain(); + } + } return; } else @@ -665,78 +946,80 @@ void LLPanelScriptLimitsRegionMemory::onClickRefresh(void* userdata) void LLPanelScriptLimitsRegionMemory::showBeacon() { -/* LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list"); + LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list"); if (!list) return; LLScrollListItem* first_selected = list->getFirstSelected(); if (!first_selected) return; - std::string name = first_selected->getColumn(1)->getValue().asString(); - std::string pos_string = first_selected->getColumn(3)->getValue().asString(); + std::string name = first_selected->getColumn(2)->getValue().asString(); + std::string pos_string = first_selected->getColumn(5)->getValue().asString(); - llinfos << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" <<llendl; - llinfos << "name = " << name << " pos = " << pos_string << llendl; - F32 x, y, z; S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z); if (matched != 3) return; LLVector3 pos_agent(x, y, z); LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); - llinfos << "name = " << name << " pos = " << pos_string << llendl; + std::string tooltip(""); - LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM);*/ + LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM); } // static void LLPanelScriptLimitsRegionMemory::onClickHighlight(void* userdata) { -/* llinfos << "LLPanelRegionGeneralInfo::onClickHighlight" << llendl; + llinfos << "LLPanelRegionGeneralInfo::onClickHighlight" << llendl; LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); if(instance) { LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); - panel->showBeacon(); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + if(panel) + { + panel->showBeacon(); + } + } return; } else { llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; -// std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); -// panel->childSetValue("loading_text", LLSD(msg_waiting)); return; - }*/ + } } -void LLPanelScriptLimitsRegionMemory::returnObjects() +void LLPanelScriptLimitsRegionMemory::returnObjectsFromParcel(S32 local_id) { -/* llinfos << "started" << llendl; LLMessageSystem *msg = gMessageSystem; LLViewerRegion* region = gAgent.getRegion(); if (!region) return; - llinfos << "got region" << llendl; LLCtrlListInterface *list = childGetListInterface("scripts_list"); if (!list || list->getItemCount() == 0) return; - llinfos << "got list" << llendl; - std::vector<LLUUID>::iterator id_itor; + std::vector<LLSD>::iterator id_itor; bool start_message = true; - for (id_itor = mObjectListIDs.begin(); id_itor != mObjectListIDs.end(); ++id_itor) + for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) { - LLUUID task_id = *id_itor; - llinfos << task_id << llendl; - if (!list->isSelected(task_id)) + LLSD element = *id_itor; + if (!list->isSelected(element["id"].asUUID())) { - llinfos << "not selected" << llendl; // Selected only continue; } - llinfos << "selected" << llendl; + + if(element["local_id"].asInteger() != local_id) + { + // Not the parcel we are looking for + continue; + } + if (start_message) { msg->newMessageFast(_PREHASH_ParcelReturnObjects); @@ -744,285 +1027,74 @@ void LLPanelScriptLimitsRegionMemory::returnObjects() msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ParcelData); - msg->addS32Fast(_PREHASH_LocalID, -1); // Whole region - msg->addS32Fast(_PREHASH_ReturnType, RT_LIST); + msg->addS32Fast(_PREHASH_LocalID, element["local_id"].asInteger()); + msg->addU32Fast(_PREHASH_ReturnType, RT_LIST); start_message = false; - llinfos << "start message" << llendl; } msg->nextBlockFast(_PREHASH_TaskIDs); - msg->addUUIDFast(_PREHASH_TaskID, task_id); - llinfos << "added id" << llendl; + msg->addUUIDFast(_PREHASH_TaskID, element["id"].asUUID()); if (msg->isSendFullFast(_PREHASH_TaskIDs)) { msg->sendReliable(region->getHost()); start_message = true; - llinfos << "sent 1" << llendl; } } if (!start_message) { msg->sendReliable(region->getHost()); - llinfos << "sent 2" << llendl; - }*/ + } } -// static -void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata) +void LLPanelScriptLimitsRegionMemory::returnObjects() { -/* llinfos << "LLPanelRegionGeneralInfo::onClickReturn" << llendl; - LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); - if(instance) + if(!mContent.has("parcels")) { - LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); - panel->returnObjects(); return; } - else - { - llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; -// std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); -// panel->childSetValue("loading_text", LLSD(msg_waiting)); - return; - }*/ -} - -///---------------------------------------------------------------------------- -// URLs Panel -///---------------------------------------------------------------------------- - -void LLPanelScriptLimitsRegionURLs::setRegionDetails(LLSD content) -{ - LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); - - S32 number_parcels = content["parcels"].size(); - - LLStringUtil::format_map_t args_parcels; - args_parcels["[PARCELS]"] = llformat ("%d", number_parcels); - std::string msg_parcels = LLTrans::getString("ScriptLimitsParcelsOwned", args_parcels); - childSetValue("parcels_listed", LLSD(msg_parcels)); - - S32 total_objects = 0; - S32 total_size = 0; + S32 number_parcels = mContent["parcels"].size(); + + // a message per parcel containing all objects to be returned from that parcel for(S32 i = 0; i < number_parcels; i++) { - std::string parcel_name = content["parcels"][i]["name"].asString(); - llinfos << parcel_name << llendl; - - S32 number_objects = content["parcels"][i]["objects"].size(); - for(S32 j = 0; j < number_objects; j++) + S32 local_id = 0; + if(mContent["parcels"][i].has("local_id")) { - if(content["parcels"][i]["objects"][j]["resources"].has("urls")) - { - S32 size = content["parcels"][i]["objects"][j]["resources"]["urls"].asInteger(); - total_size += size; - - std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString(); - LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID(); - LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID(); - - std::string owner_buf; - gCacheName->getFullName(owner_id, owner_buf); //dont care if this fails as the memory tab will request and fill the field - - LLSD element; - - element["id"] = task_id; - element["columns"][0]["column"] = "urls"; - element["columns"][0]["value"] = llformat("%d", size); - element["columns"][0]["font"] = "SANSSERIF"; - element["columns"][1]["column"] = "name"; - element["columns"][1]["value"] = name_buf; - element["columns"][1]["font"] = "SANSSERIF"; - element["columns"][2]["column"] = "owner"; - element["columns"][2]["value"] = owner_buf; - element["columns"][2]["font"] = "SANSSERIF"; - element["columns"][3]["column"] = "location"; - element["columns"][3]["value"] = parcel_name; - element["columns"][3]["font"] = "SANSSERIF"; - - list->addElement(element); - mObjectListItems.push_back(element); - total_objects++; - } + local_id = mContent["parcels"][i]["local_id"].asInteger(); + returnObjectsFromParcel(local_id); } } - - mParcelURLsUsed =total_size; - mGotParcelURLsUsed = TRUE; - populateParcelURLsText(); -} - -void LLPanelScriptLimitsRegionURLs::populateParcelURLsText() -{ - if(mGotParcelURLsUsed && mGotParcelURLsMax) - { - -#ifdef USE_SIMPLE_SUMMARY - LLStringUtil::format_map_t args_parcel_urls; - args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed); - std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsedSimple", args_parcel_urls); - childSetValue("urls_used", LLSD(msg_parcel_urls)); -#else - S32 parcel_urls_available = mParcelURLsMax - mParcelURLsUsed; - LLStringUtil::format_map_t args_parcel_urls; - args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed); - args_parcel_urls["[MAX]"] = llformat ("%d", mParcelURLsMax); - args_parcel_urls["[AVAILABLE]"] = llformat ("%d", parcel_urls_available); - std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_parcel_urls); - childSetValue("urls_used", LLSD(msg_parcel_urls)); -#endif - - childSetValue("loading_text", LLSD(std::string(""))); - - } + onClickRefresh(NULL); } -void LLPanelScriptLimitsRegionURLs::setRegionSummary(LLSD content) -{ - if(content["summary"]["available"][0]["type"].asString() == std::string("urls")) - { - mParcelURLsMax = content["summary"]["available"][0]["amount"].asInteger(); - mGotParcelURLsMax = TRUE; - } - else if(content["summary"]["available"][1]["type"].asString() == std::string("urls")) - { - mParcelURLsMax = content["summary"]["available"][1]["amount"].asInteger(); - mGotParcelURLsMax = TRUE; - } - else - { - llinfos << "summary contains no url info" << llendl; - return; - } -/* - currently this is broken on the server, so we get this value from the details section - and update via populateParcelMemoryText() when both sets of information have been returned - - when the sim is fixed this should be used instead: - if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) - { - mParcelURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); - mGotParcelURLsUsed = TRUE; - } - else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) - { - mParcelURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); - mGotParcelURLsUsed = TRUE; - } - else - { - //ERROR!!! - return; - }*/ - - populateParcelURLsText(); -} - -BOOL LLPanelScriptLimitsRegionURLs::postBuild() -{ - childSetAction("refresh_list_btn", onClickRefresh, this); - childSetAction("highlight_btn", onClickHighlight, this); - childSetAction("return_btn", onClickReturn, this); - - std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); - childSetValue("loading_text", LLSD(msg_waiting)); - return FALSE; -} - -void LLPanelScriptLimitsRegionURLs::clearList() -{ - LLCtrlListInterface *list = childGetListInterface("scripts_list"); - - if (list) - { - list->operateOnAll(LLCtrlListInterface::OP_DELETE); - } - - mGotParcelURLsUsed = FALSE; - mGotParcelURLsMax = FALSE; - - LLStringUtil::format_map_t args_parcel_urls; - std::string msg_empty_string(""); - childSetValue("urls_used", LLSD(msg_empty_string)); - childSetValue("parcels_listed", LLSD(msg_empty_string)); - - mObjectListItems.clear(); -} - -// static -void LLPanelScriptLimitsRegionURLs::onClickRefresh(void* userdata) -{ - llinfos << "Refresh clicked" << llendl; - - LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); - if(instance) - { - LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); - // use the memory panel to re-request all the info - panel_memory->clearList(); - - LLPanelScriptLimitsRegionURLs* panel_urls = (LLPanelScriptLimitsRegionURLs*)tab->getChild<LLPanel>("script_limits_region_urls_panel"); - // but the urls panel to clear itself - panel_urls->clearList(); - - panel_memory->StartRequestChain(); - return; - } - else - { - llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << llendl; - return; - } -} // static -void LLPanelScriptLimitsRegionURLs::onClickHighlight(void* userdata) +void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata) { -/* llinfos << "Highlight clicked" << llendl; + llinfos << "LLPanelRegionGeneralInfo::onClickReturn" << llendl; LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); if(instance) { LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); - // use the beacon function from the memory panel - panel->showBeacon(); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + if(panel) + { + panel->returnObjects(); + } + } return; } else { llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; -// std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); -// panel->childSetValue("loading_text", LLSD(msg_waiting)); - return; - }*/ -} - -// static -void LLPanelScriptLimitsRegionURLs::onClickReturn(void* userdata) -{ -/* llinfos << "Return clicked" << llendl; - LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); - if(instance) - { - LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); - LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); - // use the return function from the memory panel - panel->returnObjects(); return; } - else - { - llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; -// std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); -// panel->childSetValue("loading_text", LLSD(msg_waiting)); - return; - }*/ } ///---------------------------------------------------------------------------- @@ -1047,6 +1119,12 @@ BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails() void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content) { LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); + + if(!list) + { + return; + } + S32 number_attachments = content["attachments"].size(); for(int i = 0; i < number_attachments; i++) @@ -1096,6 +1174,8 @@ void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content) list->addElement(element); } } + + setAttachmentSummary(content); childSetValue("loading_text", LLSD(std::string(""))); } @@ -1122,6 +1202,69 @@ void LLPanelScriptLimitsAttachment::clearList() childSetValue("loading_text", LLSD(msg_waiting)); } +void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content) +{ + if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) + { + mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotAttachmentMemoryUsed = TRUE; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) + { + mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotAttachmentMemoryUsed = TRUE; + } + else + { + llinfos << "attachment details don't contain memory summary info" << llendl; + return; + } + + if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) + { + mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); + mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger(); + mGotAttachmentURLsUsed = TRUE; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) + { + mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); + mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger(); + mGotAttachmentURLsUsed = TRUE; + } + else + { + llinfos << "attachment details don't contain urls summary info" << llendl; + return; + } + + if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0)) + { + S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed; + + LLStringUtil::format_map_t args_attachment_memory; + args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed); + args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax); + args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available); + std::string msg_attachment_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_attachment_memory); + childSetValue("memory_used", LLSD(msg_attachment_memory)); + } + + if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0)) + { + S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed; + + LLStringUtil::format_map_t args_attachment_urls; + args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed); + args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax); + args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available); + std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls); + childSetValue("urls_used", LLSD(msg_attachment_urls)); + } +} + // static void LLPanelScriptLimitsAttachment::onClickRefresh(void* userdata) { diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index e675d14515..4c1ecc1019 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -166,10 +166,10 @@ public: BOOL StartRequestChain(); - void populateParcelMemoryText(); BOOL getLandScriptResources(); void clearList(); void showBeacon(); + void returnObjectsFromParcel(S32 local_id); void returnObjects(); private: @@ -178,69 +178,30 @@ private: const std::string& first_name, const std::string& last_name); + LLSD mContent; LLUUID mParcelId; BOOL mGotParcelMemoryUsed; + BOOL mGotParcelMemoryUsedDetails; BOOL mGotParcelMemoryMax; S32 mParcelMemoryMax; S32 mParcelMemoryUsed; + S32 mParcelMemoryUsedDetails; - std::vector<LLSD> mObjectListItems; - -protected: - -// LLRemoteParcelInfoObserver interface: -/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); -/*virtual*/ void setParcelID(const LLUUID& parcel_id); -/*virtual*/ void setErrorStatus(U32 status, const std::string& reason); - - static void onClickRefresh(void* userdata); - static void onClickHighlight(void* userdata); - static void onClickReturn(void* userdata); -}; - -///////////////////////////////////////////////////////////////////////////// -// URLs panel -///////////////////////////////////////////////////////////////////////////// - -class LLPanelScriptLimitsRegionURLs : public LLPanelScriptLimitsInfo -{ - -public: - LLPanelScriptLimitsRegionURLs() - : LLPanelScriptLimitsInfo(), - - mParcelId(LLUUID()), - mGotParcelURLsUsed(FALSE), - mGotParcelURLsMax(FALSE), - mParcelURLsMax(0), - mParcelURLsUsed(0) - { - }; - - ~LLPanelScriptLimitsRegionURLs() - { - }; - - // LLPanel - virtual BOOL postBuild(); - - void setRegionDetails(LLSD content); - void setRegionSummary(LLSD content); - - void populateParcelURLsText(); - void clearList(); - -private: - - LLUUID mParcelId; BOOL mGotParcelURLsUsed; + BOOL mGotParcelURLsUsedDetails; BOOL mGotParcelURLsMax; S32 mParcelURLsMax; S32 mParcelURLsUsed; + S32 mParcelURLsUsedDetails; std::vector<LLSD> mObjectListItems; protected: + +// LLRemoteParcelInfoObserver interface: +/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); +/*virtual*/ void setParcelID(const LLUUID& parcel_id); +/*virtual*/ void setErrorStatus(U32 status, const std::string& reason); static void onClickRefresh(void* userdata); static void onClickHighlight(void* userdata); @@ -266,11 +227,26 @@ public: void setAttachmentDetails(LLSD content); + void setAttachmentSummary(LLSD content); BOOL requestAttachmentDetails(); void clearList(); private: + BOOL mGotAttachmentMemoryUsed; + BOOL mGotAttachmentMemoryUsedDetails; + BOOL mGotAttachmentMemoryMax; + S32 mAttachmentMemoryMax; + S32 mAttachmentMemoryUsed; + S32 mAttachmentMemoryUsedDetails; + + BOOL mGotAttachmentURLsUsed; + BOOL mGotAttachmentURLsUsedDetails; + BOOL mGotAttachmentURLsMax; + S32 mAttachmentURLsMax; + S32 mAttachmentURLsUsed; + S32 mAttachmentURLsUsedDetails; + protected: static void onClickRefresh(void* userdata); diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index b05eb84e52..f154de39c9 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -2540,13 +2540,11 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde { static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - static const LLUUID& landmarks_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID(); LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID(); - if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id) || - (a_uuid == landmarks_folder_id && b_uuid == landmarks_folder_id)) + if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id)) { // *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem // or to LLInvFVBridge 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/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index bdf1ebddac..05e366523a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -317,7 +317,10 @@ BOOL LLInventoryModel::isObjectDescendentOf(const LLUUID& obj_id, const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(const LLUUID& obj_id) const { const LLInventoryObject* obj = getObject(obj_id); - const LLUUID& parent_id = obj->getParentUUID(); + + // Search up the parent chain until we get to root or an acceptable folder. + // This assumes there are no cycles in the tree else we'll get a hang. + LLUUID parent_id = obj->getParentUUID(); while (!parent_id.isNull()) { const LLViewerInventoryCategory *cat = getCategory(parent_id); @@ -329,6 +332,7 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons { return cat; } + parent_id = cat->getParentUUID(); } return NULL; } 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/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index fccf71f3cb..7bcbe334ff 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1904,7 +1904,7 @@ void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url, const LLUUID& item_id, BOOL is_running) { - llinfos << "Update Task Inventory via capability" << llendl; + llinfos << "Update Task Inventory via capability " << url << llendl; LLSD body; body["task_id"] = task_id; body["item_id"] = item_id; 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 9614be8240..7b923f4b0b 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -164,7 +164,21 @@ void LLSidepanelInventory::onWearButtonClicked() void LLSidepanelInventory::onPlayButtonClicked() { - performActionOnSelection("open"); + 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/lltoolplacer.h b/indra/newview/lltoolplacer.h index b7422380d4..df07f1854c 100644 --- a/indra/newview/lltoolplacer.h +++ b/indra/newview/lltoolplacer.h @@ -33,7 +33,6 @@ #ifndef LL_TOOLPLACER_H #define LL_TOOLPLACER_H -#include "llprimitive.h" #include "llpanel.h" #include "lltool.h" 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 c062dd1732..73e1b312fa 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -1258,7 +1258,6 @@ LLVoiceClient::LLVoiceClient() : mEarLocation(0), mSpeakerVolumeDirty(true), mSpeakerMuteDirty(true), - mSpeakerVolume(0), mMicVolume(0), mMicVolumeDirty(true), @@ -1271,6 +1270,8 @@ LLVoiceClient::LLVoiceClient() : mAPIVersion = LLTrans::getString("NotConnected"); + mSpeakerVolume = scale_speaker_volume(0); + #if LL_DARWIN || LL_LINUX || LL_SOLARIS // HACK: THIS DOES NOT BELONG HERE // When the vivox daemon dies, the next write attempt on our socket generates a SIGPIPE, which kills us. @@ -3525,7 +3526,7 @@ void LLVoiceClient::buildLocalAudioUpdates(std::ostringstream &stream) if(mSpeakerMuteDirty) { - const char *muteval = ((mSpeakerVolume == 0)?"true":"false"); + const char *muteval = ((mSpeakerVolume <= scale_speaker_volume(0))?"true":"false"); mSpeakerMuteDirty = false; @@ -5981,7 +5982,7 @@ bool LLVoiceClient::voiceEnabled() bool LLVoiceClient::voiceWorking() { - return (stateLoggedIn <= mState) && (mState <= stateLeavingSession); + return (stateLoggedIn <= mState) && (mState <= stateSessionTerminated); } void LLVoiceClient::setLipSyncEnabled(BOOL enabled) @@ -6062,7 +6063,8 @@ void LLVoiceClient::setVoiceVolume(F32 volume) if(scaled_volume != mSpeakerVolume) { - if((scaled_volume == 0) || (mSpeakerVolume == 0)) + int min_volume = scale_speaker_volume(0); + if((scaled_volume == min_volume) || (mSpeakerVolume == min_volume)) { mSpeakerMuteDirty = true; } 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_animation_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_preview.xml index 4f4288b654..1ffedde29b 100644 --- a/indra/newview/skins/default/xui/en/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_animation_preview.xml @@ -147,7 +147,11 @@ Maximum animation length is [MAX_LENGTH] seconds. name="E_ST_NO_XLT_EMOTE"> Cannot read emote name. </floater.string> - <text + <floater.string + name="E_ST_BAD_ROOT"> + Incorrect root joint name, use "hip". + </floater.string> + <text type="string" length="1" bottom="42" 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_script_limits.xml b/indra/newview/skins/default/xui/en/floater_script_limits.xml index 98c44ad1b3..6b36cdfcc5 100644 --- a/indra/newview/skins/default/xui/en/floater_script_limits.xml +++ b/indra/newview/skins/default/xui/en/floater_script_limits.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater legacy_header_height="18" + can_resize="true" height="570" help_topic="scriptlimits" layout="topleft" 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/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml index d98f690339..629d8567d1 100644 --- a/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml +++ b/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml @@ -9,7 +9,44 @@ name="script_limits_my_avatar_panel" top="0" width="480"> - <text + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + name="script_memory" + top_pad="24" + text_color="White" + width="480"> + Avatar Script Usage + </text> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="30" + name="memory_used" + top_delta="18" + width="480"> + + </text> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="30" + name="urls_used" + top_delta="18" + width="480"> + + </text> + <text type="string" length="1" follows="left|top" @@ -17,7 +54,7 @@ layout="topleft" left="10" name="loading_text" - top="10" + top="80" text_color="EmphasisColor" width="480"> Loading... @@ -25,12 +62,12 @@ <scroll_list draw_heading="true" follows="all" - height="500" + height="415" layout="topleft" left_delta="0" multi_select="true" name="scripts_list" - top_delta="17" + top="100" width="460"> <scroll_list.columns label="Size (kb)" diff --git a/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml index 0fa3c1cf2e..9dff00fa0b 100644 --- a/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml +++ b/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml @@ -33,7 +33,7 @@ top_delta="18" visible="true" width="480"> - Parcels Owned: + </text> <text type="string" @@ -45,7 +45,19 @@ name="memory_used" top_delta="18" width="480"> - Memory used: + </text> + + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="30" + name="urls_used" + top_delta="18" + width="480"> + </text> <text type="string" @@ -55,7 +67,7 @@ layout="topleft" left="10" name="loading_text" - top_delta="32" + top_delta="12" text_color="EmphasisColor" width="480"> Loading... @@ -73,7 +85,11 @@ <scroll_list.columns label="Size (kb)" name="size" - width="70" /> + width="72" /> + <scroll_list.columns + label="URLs" + name="urls" + width="48" /> <scroll_list.columns label="Object Name" name="name" @@ -83,11 +99,13 @@ name="owner" width="100" /> <scroll_list.columns - label="Parcel / Location" - name="location" + label="Parcel" + name="parcel" width="130" /> -<!-- <scroll_list.commit_callback - function="TopObjects.CommitObjectsList" />--> + <scroll_list.columns + label="Location" + name="location" + width="80" /> </scroll_list> <button follows="bottom|left" @@ -102,8 +120,8 @@ <button follows="bottom|right" height="19" - visible="false" label="Highlight" + visible="false" layout="bottomright" left="370" name="highlight_btn" @@ -112,8 +130,8 @@ <button follows="bottom|right" height="19" - visible="false" label="Return" + visible="false" layout="bottomright" name="return_btn" top="34" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index b378944e48..b4a12cfb32 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2051,6 +2051,7 @@ this texture in your inventory <string name="ScriptLimitsURLsUsed">URLs used: [COUNT] out of [MAX]; [AVAILABLE] available</string> <string name="ScriptLimitsURLsUsedSimple">URLs used: [COUNT]</string> <string name="ScriptLimitsRequestError">Error requesting information</string> + <string name="ScriptLimitsRequestNoParcelSelected">No Parcel Selected</string> <string name="ScriptLimitsRequestWrongRegion">Error: script information is only available in your current region</string> <string name="ScriptLimitsRequestWaiting">Retrieving information...</string> <string name="ScriptLimitsRequestDontOwnParcel">You do not have permission to examine this parcel</string> 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" |