diff options
168 files changed, 5889 insertions, 2667 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index 6a23e8093c..8ae828e738 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -360,6 +360,8 @@ Chaser Zaks BUG-227485 Cherry Cheevers ChickyBabes Zuzu +Chorazin Allen + BUG-229753 Christopher Organiser Ciaran Laval Cinder Roxley diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 3b39aeb56b..5d08c1f4c6 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -295,7 +295,6 @@ public: void setAllowTerraform(BOOL b){setParcelFlag(PF_ALLOW_TERRAFORM, b); } void setAllowDamage(BOOL b) { setParcelFlag(PF_ALLOW_DAMAGE, b); } void setAllowFly(BOOL b) { setParcelFlag(PF_ALLOW_FLY, b); } - void setAllowLandmark(BOOL b){ setParcelFlag(PF_ALLOW_LANDMARK, b); } void setAllowGroupScripts(BOOL b) { setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, b); } void setAllowOtherScripts(BOOL b) { setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, b); } void setAllowDeedToGroup(BOOL b) { setParcelFlag(PF_ALLOW_DEED_TO_GROUP, b); } @@ -476,11 +475,6 @@ public: BOOL getAllowFly() const { return (mParcelFlags & PF_ALLOW_FLY) ? TRUE : FALSE; } - // Remove permission restrictions for creating landmarks. - // We should eventually remove this flag completely. - BOOL getAllowLandmark() const - { return TRUE; } - BOOL getAllowGroupScripts() const { return (mParcelFlags & PF_ALLOW_GROUP_SCRIPTS) ? TRUE : FALSE; } diff --git a/indra/llinventory/llparcelflags.h b/indra/llinventory/llparcelflags.h index 25b27a281a..4cffa83cc1 100644 --- a/indra/llinventory/llparcelflags.h +++ b/indra/llinventory/llparcelflags.h @@ -33,7 +33,7 @@ const U32 PF_ALLOW_FLY = 1 << 0;// Can start flying const U32 PF_ALLOW_OTHER_SCRIPTS= 1 << 1;// Scripts by others can run. const U32 PF_FOR_SALE = 1 << 2;// Can buy this land const U32 PF_FOR_SALE_OBJECTS = 1 << 7;// Can buy all objects on this land -const U32 PF_ALLOW_LANDMARK = 1 << 3; +const U32 PF_ALLOW_LANDMARK = 1 << 3;// Always true/deprecated const U32 PF_ALLOW_TERRAFORM = 1 << 4; const U32 PF_ALLOW_DAMAGE = 1 << 5; const U32 PF_CREATE_OBJECTS = 1 << 6; diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index cce618487b..f781ff4110 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -122,6 +122,7 @@ set(llui_SOURCE_FILES lluictrl.cpp lluictrlfactory.cpp lluistring.cpp + lluiusage.cpp llundo.cpp llurlaction.cpp llurlentry.cpp @@ -241,6 +242,7 @@ set(llui_HEADER_FILES llui.h lluicolor.h lluistring.h + lluiusage.h llundo.h llurlaction.h llurlentry.h diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 9682c3bc10..0e59fdf519 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -47,6 +47,7 @@ #include "llnotificationsutil.h" #include "llrender.h" #include "lluictrlfactory.h" +#include "lluiusage.h" #include "llhelp.h" #include "lldockablefloater.h" #include "llviewereventrecorder.h" @@ -437,6 +438,13 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) setFocus(TRUE); } + if (!mFunctionName.empty()) + { + LL_DEBUGS("UIUsage") << "calling mouse down function " << mFunctionName << LL_ENDL; + LLUIUsage::instance().logCommand(mFunctionName); + LLUIUsage::instance().logControl(getPathname()); + } + /* * ATTENTION! This call fires another mouse down callback. * If you wish to remove this call emit that signal directly diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index f5b242fdfc..c39e44200c 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -37,7 +37,8 @@ typedef enum e_chat_source_type CHAT_SOURCE_SYSTEM = 0, CHAT_SOURCE_AGENT = 1, CHAT_SOURCE_OBJECT = 2, - CHAT_SOURCE_UNKNOWN = 3 + CHAT_SOURCE_TELEPORT = 3, + CHAT_SOURCE_UNKNOWN = 4 } EChatSourceType; typedef enum e_chat_type @@ -64,7 +65,8 @@ typedef enum e_chat_style { CHAT_STYLE_NORMAL, CHAT_STYLE_IRC, - CHAT_STYLE_HISTORY + CHAT_STYLE_HISTORY, + CHAT_STYLE_TELEPORT_SEP }EChatStyle; // A piece of chat diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index e9c980ad9a..8ceb411ede 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -58,6 +58,7 @@ #include "llhelp.h" #include "llmultifloater.h" #include "llsdutil.h" +#include "lluiusage.h" #include <boost/foreach.hpp> @@ -198,7 +199,9 @@ LLFloater::Params::Params() help_pressed_image("help_pressed_image"), open_callback("open_callback"), close_callback("close_callback"), - follows("follows") + follows("follows"), + rel_x("rel_x", 0), + rel_y("rel_y", 0) { changeDefault(visible, false); } @@ -267,6 +270,8 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) mHasBeenDraggedWhileMinimized(FALSE), mPreviousMinimizedBottom(0), mPreviousMinimizedLeft(0), + mDefaultRelativeX(p.rel_x), + mDefaultRelativeY(p.rel_y), mMinimizeSignal(NULL) // mNotificationContext(NULL) { @@ -505,7 +510,12 @@ void LLFloater::destroy() // virtual LLFloater::~LLFloater() { - LLFloaterReg::removeInstance(mInstanceName, mKey); + if (!isDead()) + { + // If it's dead, instance is supposed to be already removed, and + // in case of single instance we can remove new one by accident + LLFloaterReg::removeInstance(mInstanceName, mKey); + } if( gFocusMgr.childHasKeyboardFocus(this)) { @@ -934,6 +944,15 @@ bool LLFloater::applyRectControl() saved_rect = true; } + else if ((mDefaultRelativeX != 0) && (mDefaultRelativeY != 0)) + { + mPosition.mX = mDefaultRelativeX; + mPosition.mY = mDefaultRelativeY; + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + applyRelativePosition(); + + saved_rect = true; + } // remember updated position if (rect_specified) @@ -1631,6 +1650,7 @@ void LLFloater::bringToFront( S32 x, S32 y ) // virtual void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key) { + LLUIUsage::instance().logFloater(getInstanceName()); LLMultiFloater* hostp = getHost(); if (hostp) { @@ -3198,6 +3218,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p) mSingleInstance = p.single_instance; mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; + mDefaultRelativeX = p.rel_x; + mDefaultRelativeY = p.rel_y; + mPositioning = p.positioning; mSaveRect = p.save_rect; diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index f8c04e8a2f..2672d600c6 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -172,6 +172,9 @@ public: Optional<S32> header_height, legacy_header_height; // HACK see initFromXML() + Optional<F32> rel_x, + rel_y; + // Images for top-right controls Optional<LLUIImage*> close_image, restore_image, @@ -521,6 +524,9 @@ private: BOOL mHasBeenDraggedWhileMinimized; S32 mPreviousMinimizedBottom; S32 mPreviousMinimizedLeft; + + F32 mDefaultRelativeX; + F32 mDefaultRelativeY; }; diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 85e07fc6a6..36a0cb0fd0 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -32,6 +32,7 @@ #include "llfloater.h" #include "llmultifloater.h" #include "llfloaterreglistener.h" +#include "lluiusage.h" //******************************************************* @@ -57,6 +58,12 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con } //static +bool LLFloaterReg::isRegistered(const std::string& name) +{ + return sBuildMap.find(name) != sBuildMap.end(); +} + +//static LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name) { const std::string& groupname = sGroupMap[name]; @@ -472,7 +479,6 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& std::string name = sdname.asString(); LLFloater* instance = getInstance(name, key); - if (!instance) { LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL; diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index e3b17dcb4f..a457a15673 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -85,6 +85,7 @@ public: static void add(const std::string& name, const std::string& file, const LLFloaterBuildFunc& func, const std::string& groupname = LLStringUtil::null); + static bool isRegistered(const std::string& name); // Helpers static LLFloater* getLastFloaterInGroup(const std::string& name); diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index aa5779d45f..f84625bea7 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -283,6 +283,9 @@ public: void resetContextMenu() { setContextMenu(NULL); }; + void setBgImage(LLPointer<LLUIImage> image) { mBgImage = image; } + void setBgImageFocused(LLPointer<LLUIImage> image) { mBgImageFocused = image; } + private: // private helper methods diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 37dbe9b40e..cdaf03ebde 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -79,7 +79,7 @@ const U32 LEFT_PAD_PIXELS = 3; const U32 LEFT_WIDTH_PIXELS = 15; const U32 LEFT_PLAIN_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS; -const U32 RIGHT_PAD_PIXELS = 2; +const U32 RIGHT_PAD_PIXELS = 7; const U32 RIGHT_WIDTH_PIXELS = 15; const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS; @@ -95,7 +95,7 @@ const std::string SEPARATOR_NAME("separator"); const std::string VERTICAL_SEPARATOR_LABEL( "|" ); const std::string LLMenuGL::BOOLEAN_TRUE_PREFIX( "\xE2\x9C\x94" ); // U+2714 HEAVY CHECK MARK -const std::string LLMenuGL::BRANCH_SUFFIX( "\xE2\x96\xB6" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE +const std::string LLMenuGL::BRANCH_SUFFIX( "\xe2\x96\xb8" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE const std::string LLMenuGL::ARROW_UP ("^^^^^^^"); const std::string LLMenuGL::ARROW_DOWN("vvvvvvv"); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 06ec648178..b791a19c2b 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -77,6 +77,7 @@ LLNotificationForm::FormButton::FormButton() text("text"), ignore("ignore"), is_default("default"), + width("width", 0), type("type") { // set type here so it gets serialized diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 2f4578da17..b0b56cf599 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -191,6 +191,7 @@ public: Mandatory<std::string> text; Optional<std::string> ignore; Optional<bool> is_default; + Optional<S32> width; Mandatory<std::string> type; diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 1fdd05a11c..bafeef41fb 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -34,7 +34,11 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) : LLUICtrl(p), mSearchButton(NULL), - mClearButton(NULL) + mClearButton(NULL), + mEditorImage(p.background_image), + mEditorImageFocused(p.background_image_focused), + mEditorSearchImage(p.background_image_highlight), + mHighlightTextField(p.highlight_text_field) { S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height; S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad; @@ -57,6 +61,8 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) // Set up line editor. LLLineEditor::Params line_editor_params(p); line_editor_params.name("filter edit box"); + line_editor_params.background_image(p.background_image); + line_editor_params.background_image_focused(p.background_image_focused); line_editor_params.rect(getLocalRect()); line_editor_params.follows.flags(FOLLOWS_ALL); line_editor_params.text_pad_left(text_pad_left); @@ -104,6 +110,20 @@ void LLSearchEditor::draw() if (mClearButton) mClearButton->setVisible(!mSearchEditor->getWText().empty()); + if (mHighlightTextField) + { + if (!mSearchEditor->getWText().empty()) + { + mSearchEditor->setBgImage(mEditorSearchImage); + mSearchEditor->setBgImageFocused(mEditorSearchImage); + } + else + { + mSearchEditor->setBgImage(mEditorImage); + mSearchEditor->setBgImageFocused(mEditorImageFocused); + } + } + LLUICtrl::draw(); } diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h index 3b12868225..c0f3c1d60c 100644 --- a/indra/llui/llsearcheditor.h +++ b/indra/llui/llsearcheditor.h @@ -47,14 +47,23 @@ public: Optional<LLButton::Params> search_button, clear_button; Optional<bool> search_button_visible, - clear_button_visible; + clear_button_visible, + highlight_text_field; Optional<commit_callback_t> keystroke_callback; + Optional<LLUIImage*> background_image, + background_image_focused, + background_image_highlight; + Params() : search_button("search_button"), search_button_visible("search_button_visible"), clear_button("clear_button"), - clear_button_visible("clear_button_visible") + clear_button_visible("clear_button_visible"), + highlight_text_field("highlight_text_field"), + background_image("background_image"), + background_image_focused("background_image_focused"), + background_image_highlight("background_image_highlight") {} }; @@ -93,6 +102,13 @@ protected: LLLineEditor* mSearchEditor; LLButton* mSearchButton; LLButton* mClearButton; + + LLPointer<LLUIImage> mEditorImage; + LLPointer<LLUIImage> mEditorImageFocused; + LLPointer<LLUIImage> mEditorSearchImage; + LLPointer<LLUIImage> mEditorSearchImageFocused; + + bool mHighlightTextField; }; #endif // LL_SEARCHEDITOR_H diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index e6b43da8e5..459fdcf2ae 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -38,6 +38,7 @@ #include "llrender.h" #include "llfloater.h" #include "lltrans.h" +#include "lluiusage.h" //---------------------------------------------------------------------------- @@ -1556,6 +1557,8 @@ BOOL LLTabContainer::setTab(S32 which) if (is_selected) { + LLUIUsage::instance().logPanel(tuple->mTabPanel->getName()); + // Make sure selected tab is within scroll region if (mIsVertical) { diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index e6f466ec78..4868c66d1b 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -967,6 +967,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id) executeStopParam.function_name = executeStopFunction; executeStopParam.parameter = commandp->executeStopParameters(); LLUICtrl::commit_callback_t execute_func = initCommitCallback(executeParam); + button->setFunctionName(commandp->executeFunctionName()); + LL_DEBUGS("UIUsage") << "button function name a -> " << commandp->executeFunctionName() << LL_ENDL; LLUICtrl::commit_callback_t stop_func = initCommitCallback(executeStopParam); button->setMouseDownCallback(boost::bind(&LLToolBarButton::callIfEnabled, button, execute_func, _1, _2)); @@ -974,6 +976,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id) } else { + button->setFunctionName(commandp->executeFunctionName()); + LL_DEBUGS("UIUsage") << "button function name b -> " << commandp->executeFunctionName() << LL_ENDL; button->setCommitCallback(executeParam); } diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 544a76e8d5..5924542a19 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -35,6 +35,7 @@ #include "lluictrlfactory.h" #include "lltabcontainer.h" #include "llaccordionctrltab.h" +#include "lluiusage.h" static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl"); @@ -282,6 +283,7 @@ LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCa else { std::string function_name = cb.function_name; + setFunctionName(function_name); commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name)); if (func) { @@ -422,7 +424,19 @@ BOOL LLUICtrl::canFocusChildren() const void LLUICtrl::onCommit() { if (mCommitSignal) - (*mCommitSignal)(this, getValue()); + { + if (!mFunctionName.empty()) + { + LL_DEBUGS("UIUsage") << "calling commit function " << mFunctionName << LL_ENDL; + LLUIUsage::instance().logCommand(mFunctionName); + LLUIUsage::instance().logControl(getPathname()); + } + else + { + //LL_DEBUGS("UIUsage") << "calling commit function " << "UNKNOWN" << LL_ENDL; + } + (*mCommitSignal)(this, getValue()); + } } //virtual @@ -597,6 +611,12 @@ void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control) setVisible(!(mMakeInvisibleControlVariable->getValue().asBoolean())); } } + +void LLUICtrl::setFunctionName(const std::string& function_name) +{ + mFunctionName = function_name; +} + // static bool LLUICtrl::controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type) { diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 7360bd7659..67dd24341c 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -183,6 +183,8 @@ public: void setMakeVisibleControlVariable(LLControlVariable* control); void setMakeInvisibleControlVariable(LLControlVariable* control); + void setFunctionName(const std::string& function_name); + virtual void setTentative(BOOL b); virtual BOOL getTentative() const; virtual void setValue(const LLSD& value); @@ -310,6 +312,8 @@ protected: LLControlVariable* mMakeInvisibleControlVariable; boost::signals2::connection mMakeInvisibleControlConnection; + std::string mFunctionName; + static F32 sActiveControlTransparency; static F32 sInactiveControlTransparency; diff --git a/indra/llui/lluiusage.cpp b/indra/llui/lluiusage.cpp new file mode 100644 index 0000000000..ccae6643b9 --- /dev/null +++ b/indra/llui/lluiusage.cpp @@ -0,0 +1,146 @@ +/** +* @file lluiuisage.cpp +* @brief Source file for LLUIUsage +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "linden_common.h" +#include "lluiusage.h" +#include <boost/algorithm/string.hpp> + +LLUIUsage::LLUIUsage() +{ +} + +LLUIUsage::~LLUIUsage() +{ +} + +// static +std::string LLUIUsage::sanitized(const std::string& s) +{ + // Remove characters that make the ViewerStats db unhappy + std::string result(s); + std::replace(result.begin(), result.end(), '.', '_'); + std::replace(result.begin(), result.end(), ' ', '_'); + return result; +} + +// static +void LLUIUsage::setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val) +{ + // Keep the last max_elts components of the specified path + std::vector<std::string> fields; + boost::split(fields, path, boost::is_any_of("/")); + auto first_pos = std::max(fields.begin(), fields.end() - max_elts); + auto end_pos = fields.end(); + std::vector<std::string> last_fields(first_pos,end_pos); + + setLLSDNested(sd, last_fields, val); +} + +// setLLSDNested() +// Accomplish the equivalent of +// sd[fields[0]][fields[1]]... = val; +// for an arbitrary number of fields. +// This might be useful as an LLSD utility function; is not specific to LLUIUsage +// +// static +void LLUIUsage::setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val) +{ + LLSD* fsd = &sd; + for (auto it=fields.begin(); it!=fields.end(); ++it) + { + if (it == fields.end()-1) + { + (*fsd)[*it] = val; + } + else + { + if (!(*fsd)[*it].isMap()) + { + (*fsd)[*it] = LLSD::emptyMap(); + } + fsd = &(*fsd)[*it]; + } + } +} + +void LLUIUsage::logCommand(const std::string& command) +{ + mCommandCounts[sanitized(command)]++; + LL_DEBUGS("UIUsage") << "command " << command << LL_ENDL; +} + +void LLUIUsage::logControl(const std::string& control) +{ + mControlCounts[sanitized(control)]++; + LL_DEBUGS("UIUsage") << "control " << control << LL_ENDL; +} + + +void LLUIUsage::logFloater(const std::string& floater) +{ + mFloaterCounts[sanitized(floater)]++; + LL_DEBUGS("UIUsage") << "floater " << floater << LL_ENDL; +} + +void LLUIUsage::logPanel(const std::string& p) +{ + mPanelCounts[sanitized(p)]++; + LL_DEBUGS("UIUsage") << "panel " << p << LL_ENDL; +} + +LLSD LLUIUsage::asLLSD() const +{ + LLSD result; + for (auto const& it : mCommandCounts) + { + result["commands"][it.first] = LLSD::Integer(it.second); + } + for (auto const& it : mControlCounts) + { + setLLSDPath(result["controls"], it.first, 2, LLSD::Integer(it.second)); + } + for (auto const& it : mFloaterCounts) + { + result["floaters"][it.first] = LLSD::Integer(it.second); + } + for (auto const& it : mPanelCounts) + { + result["panels"][it.first] = LLSD::Integer(it.second); + } + return result; +} + +// Clear up some junk content generated during initial login/UI initialization +void LLUIUsage::clear() +{ + + LL_DEBUGS("UIUsage") << "clear" << LL_ENDL; + mCommandCounts.clear(); + mControlCounts.clear(); + mFloaterCounts.clear(); + mPanelCounts.clear(); +} + diff --git a/indra/llui/lluiusage.h b/indra/llui/lluiusage.h new file mode 100644 index 0000000000..a30cd80db3 --- /dev/null +++ b/indra/llui/lluiusage.h @@ -0,0 +1,57 @@ +/** +* @file lluiuisage.h +* @brief Header file for LLUIUsage +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLUIUSAGE_H +#define LL_LLUIUSAGE_H + +#include <map> +#include "llsd.h" +#include "llsingleton.h" + +// UIUsage tracking to see which operations and UI elements are most popular in a session +class LLUIUsage : public LLSingleton<LLUIUsage> +{ +public: + LLSINGLETON(LLUIUsage); + ~LLUIUsage(); +public: + static std::string sanitized(const std::string& s); + static void setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val); + static void setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val); + void logCommand(const std::string& command); + void logControl(const std::string& control); + void logFloater(const std::string& floater); + void logPanel(const std::string& p); + LLSD asLLSD() const; + void clear(); +private: + std::map<std::string,U32> mCommandCounts; + std::map<std::string,U32> mControlCounts; + std::map<std::string,U32> mFloaterCounts; + std::map<std::string,U32> mPanelCounts; +}; + +#endif // LLUIUIUSAGE.h diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp index 723643dd25..6e0aef740d 100644 --- a/indra/llui/llvirtualtrackball.cpp +++ b/indra/llui/llvirtualtrackball.cpp @@ -348,6 +348,42 @@ LLQuaternion LLVirtualTrackball::getRotation() const return mValue; } +// static +void LLVirtualTrackball::getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation) +{ + // LLQuaternion has own function to get azimuth, but it doesn't appear to return correct values (meant for 2d?) + LLVector3 point = VectorZero * quat; + + if (!is_approx_zero(point.mV[VX]) || !is_approx_zero(point.mV[VY])) + { + azimuth = atan2f(point.mV[VX], point.mV[VY]); + } + else + { + azimuth = 0; + } + + azimuth -= F_PI_BY_TWO; + + if (azimuth < 0) + { + azimuth += F_PI * 2; + } + + // while vector is '1', F32 is not sufficiently precise and we can get + // values like 1.0000012 which will result in -90deg angle instead of 90deg + F32 z = llclamp(point.mV[VZ], -1.f, 1.f); + elevation = asin(z); // because VectorZero's length is '1' +} + +// static +void LLVirtualTrackball::getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation) +{ + getAzimuthAndElevation(quat, azimuth, elevation); + azimuth *= RAD_TO_DEG; + elevation *= RAD_TO_DEG; +} + BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask) { if (hasMouseCapture()) @@ -409,6 +445,10 @@ BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask) mValue *= az_quat; } + // we are doing a lot of F32 mathematical operations with loss of precision, + // re-normalize to compensate + mValue.normalize(); + mPrevX = x; mPrevY = y; onCommit(); diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h index 2d4b1ece17..c7a893877b 100644 --- a/indra/llui/llvirtualtrackball.h +++ b/indra/llui/llvirtualtrackball.h @@ -96,6 +96,9 @@ public: void setRotation(const LLQuaternion &value); LLQuaternion getRotation() const; + static void getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation); + static void getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation); + protected: friend class LLUICtrlFactory; LLVirtualTrackball(const Params&); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index fc8d8b805b..424fd17707 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -209,6 +209,7 @@ set(viewer_SOURCE_FILES llflexibleobject.cpp llfloaterabout.cpp llfloaterbvhpreview.cpp + llfloateraddpaymentmethod.cpp llfloaterauction.cpp llfloaterautoreplacesettings.cpp llfloateravatar.cpp @@ -232,6 +233,7 @@ set(viewer_SOURCE_FILES llfloatercolorpicker.cpp llfloaterconversationlog.cpp llfloaterconversationpreview.cpp + llfloatercreatelandmark.cpp llfloaterdeleteprefpreset.cpp llfloaterdestinations.cpp llfloatereditenvironmentbase.cpp @@ -254,6 +256,7 @@ set(viewer_SOURCE_FILES llfloaterhandler.cpp llfloaterhelpbrowser.cpp llfloaterhoverheight.cpp + llfloaterhowto.cpp llfloaterhud.cpp llfloaterimagepreview.cpp llfloaterimsessiontab.cpp @@ -636,6 +639,7 @@ set(viewer_SOURCE_FILES llurl.cpp llurldispatcher.cpp llurldispatcherlistener.cpp + llurlfloaterdispatchhandler.cpp llurlhistory.cpp llurllineeditorctrl.cpp llurlwhitelist.cpp @@ -844,6 +848,7 @@ set(viewer_HEADER_FILES llflexibleobject.h llfloaterabout.h llfloaterbvhpreview.h + llfloateraddpaymentmethod.h llfloaterauction.h llfloaterautoreplacesettings.h llfloateravatar.h @@ -867,6 +872,7 @@ set(viewer_HEADER_FILES llfloatercolorpicker.h llfloaterconversationlog.h llfloaterconversationpreview.h + llfloatercreatelandmark.h llfloaterdeleteprefpreset.h llfloaterdestinations.h llfloatereditenvironmentbase.h @@ -889,6 +895,7 @@ set(viewer_HEADER_FILES llfloaterhandler.h llfloaterhelpbrowser.h llfloaterhoverheight.h + llfloaterhowto.h llfloaterhud.h llfloaterimagepreview.h llfloaterimnearbychat.h @@ -1264,6 +1271,7 @@ set(viewer_HEADER_FILES llurl.h llurldispatcher.h llurldispatcherlistener.h + llurlfloaterdispatchhandler.h llurlhistory.h llurllineeditorctrl.h llurlwhitelist.h diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index e786022da5..22beed373e 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.20 +6.4.21 diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 9a4ab8b44b..d0480ca47e 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -88,8 +88,10 @@ icon="Command_HowTo_Icon" label_ref="Command_HowTo_Label" tooltip_ref="Command_HowTo_Tooltip" - execute_function="Help.ToggleHowTo" - is_running_function="Help.HowToVisible" + execute_function="Floater.ToggleOrBringToFront" + execute_parameters="guidebook" + is_running_function="Floater.IsOpen" + is_running_parameters="guidebook" /> <command name="inventory" available_in_toybox="true" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 58a4c11ed8..b8e37ed532 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4714,6 +4714,17 @@ <key>Value</key> <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> </map> + <key>GuidebookURL</key> + <map> + <key>Comment</key> + <string>URL for Guidebook content</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>http://guidebooks.secondlife.io/welcome/index.html</string> + </map> <key>HighResSnapshot</key> <map> <key>Comment</key> @@ -14414,7 +14425,53 @@ <key>Value</key> <integer>44125</integer> </map> - <key>VoiceCallsFriendsOnly</key> + + <key>VivoxVadAuto</key> + <map> + <key>Comment</key> + <string>A flag indicating if the automatic VAD is enabled (1) or disabled (0). The individual settings are ignored if the auto-mode is enabled</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>VivoxVadHangover</key> + <map> + <key>Comment</key> + <string>The time (in milliseconds) that it takes or the VAD to switch back to silence from speech mode after the last speech frame has been detected</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>2000</integer> + </map> + <key>VivoxVadNoiseFloor</key> + <map> + <key>Comment</key> + <string>A dimensionless value between 0 and 20000 (default 576) that controls the maximum level at which the noise floor may be set at by the VAD's noise tracking</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>576</integer> + </map> + <key>VivoxVadSensitivity</key> + <map> + <key>Comment</key> + <string> + A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>VoiceCallsFriendsOnly</key> <map> <key>Comment</key> <string>(Deprecated) Only accept voice calls from residents on your friends list</string> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index c65bc0fa50..3c50493d79 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -387,6 +387,7 @@ LLAgent::LLAgent() : mTeleportFinishedSlot(), mTeleportFailedSlot(), mIsMaturityRatingChangingDuringTeleport(false), + mTPNeedsNeabyChatSeparator(false), mMaturityRatingChange(0U), mIsDoSendMaturityPreferenceToServer(false), mMaturityPreferenceRequestId(0U), @@ -3934,6 +3935,7 @@ void LLAgent::clearTeleportRequest() LLVoiceClient::getInstance()->setHidden(FALSE); } mTeleportRequest.reset(); + mTPNeedsNeabyChatSeparator = false; } void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange) @@ -3942,6 +3944,12 @@ void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange) mMaturityRatingChange = pMaturityRatingChange; } +void LLAgent::sheduleTeleportIM() +{ + // is supposed to be called during teleport so we are still waiting for parcel + mTPNeedsNeabyChatSeparator = true; +} + bool LLAgent::hasPendingTeleportRequest() { return ((mTeleportRequest != NULL) && @@ -3989,6 +3997,12 @@ void LLAgent::startTeleportRequest() void LLAgent::handleTeleportFinished() { LL_INFOS("Teleport") << "Agent handling teleport finished." << LL_ENDL; + if (mTPNeedsNeabyChatSeparator) + { + // parcel is ready at this point + addTPNearbyChatSeparator(); + mTPNeedsNeabyChatSeparator = false; + } clearTeleportRequest(); mTeleportCanceled.reset(); if (mIsMaturityRatingChangingDuringTeleport) @@ -4051,6 +4065,44 @@ void LLAgent::handleTeleportFailed() LLNotificationsUtil::add("PreferredMaturityChanged", args); mIsMaturityRatingChangingDuringTeleport = false; } + + mTPNeedsNeabyChatSeparator = false; +} + +/*static*/ +void LLAgent::addTPNearbyChatSeparator() +{ + LLViewerRegion* agent_region = gAgent.getRegion(); + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (!agent_region || !agent_parcel) + { + return; + } + + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); + if (nearby_chat) + { + std::string location_name; + LLAgentUI::ELocationFormat format = LLAgentUI::LOCATION_FORMAT_NO_MATURITY; + + // Might be better to provide slurl to chat + if (!LLAgentUI::buildLocationString(location_name, format)) + { + location_name = "Teleport to new region"; // Shouldn't happen + } + + LLChat chat; + chat.mFromName = location_name; + chat.mMuted = FALSE; + chat.mFromID = LLUUID::null; + chat.mSourceType = CHAT_SOURCE_TELEPORT; + chat.mChatStyle = CHAT_STYLE_TELEPORT_SEP; + chat.mText = ""; + + LLSD args; + args["do_not_log"] = TRUE; + nearby_chat->addMessage(chat, true, args); + } } /*static*/ diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index d46c99db8c..a792d3e11f 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -653,6 +653,7 @@ public: void restartFailedTeleportRequest(); void clearTeleportRequest(); void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange); + void sheduleTeleportIM(); private: @@ -669,6 +670,7 @@ private: boost::signals2::connection mTeleportFailedSlot; bool mIsMaturityRatingChangingDuringTeleport; + bool mTPNeedsNeabyChatSeparator; U8 mMaturityRatingChange; bool hasPendingTeleportRequest(); @@ -685,6 +687,7 @@ private: void handleTeleportFinished(); void handleTeleportFailed(); + static void addTPNearbyChatSeparator(); static void onCapabilitiesReceivedAfterTeleport(); //-------------------------------------------------------------------- diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 053c0a5ab7..c0971ba943 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -59,6 +59,7 @@ #include "llslurl.h" #include "llstartup.h" #include "llfocusmgr.h" +#include "llurlfloaterdispatchhandler.h" #include "llviewerjoystick.h" #include "llallocator.h" #include "llcalc.h" @@ -918,6 +919,7 @@ bool LLAppViewer::init() // Load translations for tooltips LLFloater::initClass(); + LLUrlFloaterDispatchHandler::registerInDispatcher(); ///////////////////////////////////////////////// diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index 856eb3414e..f41eb3daf4 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -253,6 +253,19 @@ std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_ return LLTrans::getString(payment_text); } +//static +bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avatar_data) +{ + // Special accounts like M Linden don't have payment info revealed. + if (!avatar_data->caption_text.empty()) return true; + + // Linden employees don't have payment info revealed + const S32 LINDEN_EMPLOYEE_INDEX = 3; + if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return true; + + return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED)); +} + void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**) { LLAvatarData avatar_data; diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index d5c5c75c69..b063048c26 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -232,6 +232,8 @@ public: // Used for profiles, inspectors. static std::string paymentInfo(const LLAvatarData* avatar_data); + static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data); + static void processAvatarPropertiesReply(LLMessageSystem* msg, void**); static void processAvatarInterestsReply(LLMessageSystem* msg, void**); diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 3ab5c669c4..e400609a74 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -58,6 +58,7 @@ #include "llmultigesture.h" #include "llui.h" #include "lluictrlfactory.h" +#include "lluiusage.h" // // Globals @@ -566,6 +567,8 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL // as soon as we say something, we no longer care about teaching the user // how to chat gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE); + + LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command // Look for "/20 foo" channel chats. S32 channel = 0; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 2ba2c6d8b5..c110e0d815 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -122,6 +122,7 @@ public: mUserNameFont(NULL), mUserNameTextBox(NULL), mTimeBoxTextBox(NULL), + mNeedsTimeBox(true), mAvatarNameCacheConnection() {} @@ -643,8 +644,19 @@ public: user_name->setReadOnlyColor(style_params.readonly_color()); user_name->setColor(style_params.color()); - if (chat.mFromName.empty() - || mSourceType == CHAT_SOURCE_SYSTEM) + if (mSourceType == CHAT_SOURCE_TELEPORT + && chat.mChatStyle == CHAT_STYLE_TELEPORT_SEP) + { + mFrom = chat.mFromName; + mNeedsTimeBox = false; + user_name->setValue(mFrom); + updateMinUserNameWidth(); + LLColor4 sep_color = LLUIColorTable::instance().getColor("ChatTeleportSeparatorColor"); + setTransparentColor(sep_color); + mTimeBoxTextBox->setVisible(FALSE); + } + else if (chat.mFromName.empty() + || mSourceType == CHAT_SOURCE_SYSTEM) { mFrom = LLTrans::getString("SECOND_LIFE"); if(!chat.mFromName.empty() && (mFrom != chat.mFromName)) @@ -728,6 +740,9 @@ public: case CHAT_SOURCE_SYSTEM: icon->setValue(LLSD("SL_Logo")); break; + case CHAT_SOURCE_TELEPORT: + icon->setValue(LLSD("Command_Destinations_Icon")); + break; case CHAT_SOURCE_UNKNOWN: icon->setValue(LLSD("Unknown_Icon")); } @@ -766,7 +781,7 @@ public: S32 user_name_width = user_name_rect.getWidth(); S32 time_box_width = time_box->getRect().getWidth(); - if (!time_box->getVisible() && user_name_width > mMinUserNameWidth) + if (mNeedsTimeBox && !time_box->getVisible() && user_name_width > mMinUserNameWidth) { user_name_rect.mRight -= time_box_width; user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight()); @@ -968,6 +983,8 @@ protected: LLTextBox* mUserNameTextBox; LLTextBox* mTimeBoxTextBox; + bool mNeedsTimeBox; + private: boost::signals2::connection mAvatarNameCacheConnection; }; @@ -1202,6 +1219,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY; + bool teleport_separator = chat.mSourceType == CHAT_SOURCE_TELEPORT; // We graying out chat history by graying out messages that contains full date in a time string if (message_from_log) { @@ -1222,14 +1240,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL LLStyle::Params timestamp_style(body_message_params); // out of the timestamp - if (args["show_time"].asBoolean()) - { - if (!message_from_log) + if (args["show_time"].asBoolean() && !teleport_separator) { - LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor"); - timestamp_style.color(timestamp_color); - timestamp_style.readonly_color(timestamp_color); - } + if (!message_from_log) + { + LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor"); + timestamp_style.color(timestamp_color); + timestamp_style.readonly_color(timestamp_color); + } mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style); prependNewLineState = false; } @@ -1272,6 +1290,13 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL prependNewLineState, link_params); prependNewLineState = false; } + else if (teleport_separator) + { + std::string tp_text = LLTrans::getString("teleport_preamble_compact_chat"); + mEditor->appendText(tp_text + " <nolink>" + chat.mFromName + "</nolink>", + prependNewLineState, body_message_params); + prependNewLineState = false; + } else { mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, @@ -1290,8 +1315,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL p.right_pad = mRightWidgetPad; LLDate new_message_time = LLDate::now(); - - if (mLastFromName == chat.mFromName + if (!teleport_separator + && mLastFromName == chat.mFromName && mLastFromID == chat.mFromID && mLastMessageTime.notNull() && (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0 @@ -1314,7 +1339,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL p.top_pad = 0; else p.top_pad = mTopHeaderPad; - p.bottom_pad = mBottomHeaderPad; + if (teleport_separator) + { + p.bottom_pad = mBottomSeparatorPad; + } + else + { + p.bottom_pad = mBottomHeaderPad; + } if (!view) { LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL; @@ -1392,9 +1424,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } } } - // usual messages showing - else + else if(!teleport_separator) { std::string message = irc_me ? chat.mText.substr(3) : chat.mText; @@ -1427,7 +1458,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL if (square_brackets) { message += "]"; - } + } mEditor->appendText(message, prependNewLineState, body_message_params); prependNewLineState = false; diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp index d4fc1fe64d..232e461fd0 100644 --- a/indra/newview/llcurrencyuimanager.cpp +++ b/indra/newview/llcurrencyuimanager.cpp @@ -454,7 +454,7 @@ void LLCurrencyUIManager::Impl::updateUI() if (!mUserEnteredCurrencyBuy) { - if (!mZeroMessage.empty() && mUserCurrencyBuy == 0) + if (mUserCurrencyBuy == 0) { lindenAmount->setText(LLStringUtil::null); } @@ -467,8 +467,9 @@ void LLCurrencyUIManager::Impl::updateUI() } } - mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", getLocalEstimate()); - mPanel.getChildView("currency_est")->setVisible( hasEstimate() && mUserCurrencyBuy > 0); + std::string estimated = (mUserCurrencyBuy == 0) ? mPanel.getString("estimated_zero") : getLocalEstimate(); + mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", estimated); + mPanel.getChildView("currency_est")->setVisible( hasEstimate() || mUserCurrencyBuy == 0); mPanel.getChildView("currency_links")->setVisible( mSupportsInternationalBilling); mPanel.getChildView("exchange_rate_note")->setVisible( mSupportsInternationalBilling); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 74c1b99e4d..190051d763 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -327,7 +327,7 @@ namespace std::istringstream llsdData(llsdRaw); if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length())) { - LL_WARNS() << "LLExperienceLogDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; + LL_WARNS() << "LLEnvironmentPushDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; } } @@ -785,11 +785,11 @@ namespace } //========================================================================= -const F32Seconds LLEnvironment::TRANSITION_INSTANT(0.0f); -const F32Seconds LLEnvironment::TRANSITION_FAST(1.0f); -const F32Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f); -const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f); -const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f); +const F64Seconds LLEnvironment::TRANSITION_INSTANT(0.0f); +const F64Seconds LLEnvironment::TRANSITION_FAST(1.0f); +const F64Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f); +const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f); +const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f); const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb"); const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c"); @@ -1217,28 +1217,24 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version) { - setEnvironment(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET); + setEnvironment(env, assetId, TRANSITION_DEFAULT, env_version); } - void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, - LLSettingsDay::Seconds daylength, - LLSettingsDay::Seconds dayoffset, + LLSettingsBase::Seconds transition, S32 env_version) { LLSettingsVOBase::getSettingsAsset(assetId, - [this, env, daylength, dayoffset, env_version](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) + [this, env, env_version, transition](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { - onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status, env_version); + onSetEnvAssetLoaded(env, asset_id, settings, transition, status, env_version); }); } void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, - LLSettingsDay::Seconds daylength, - LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status, S32 env_version) @@ -1685,7 +1681,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI if (!envinfo->mDayCycle) { clearEnvironment(ENV_PARCEL); - setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion); + setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion); updateEnvironment(); } else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER) @@ -1693,7 +1689,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI { LL_WARNS("ENVIRONMENT") << "Invalid day cycle for region" << LL_ENDL; clearEnvironment(ENV_PARCEL); - setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion); + setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion); updateEnvironment(); } else @@ -2939,17 +2935,15 @@ bool LLEnvironment::loadFromSettings() if (env_data.has("day_id")) { - LLSettingsDay::Seconds length = LLSettingsDay::Seconds(env_data["day_length"].asInteger()); - LLSettingsDay::Seconds offset = LLSettingsDay::Seconds(env_data["day_offset"].asInteger()); LLUUID assetId = env_data["day_id"].asUUID(); LLSettingsVOBase::getSettingsAsset(assetId, - [this, length, offset, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) + [this, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { // Day should be always applied first, // otherwise it will override sky or water that was set earlier // so wait for asset to load before applying sky/water - onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, length, offset, TRANSITION_DEFAULT, status, NO_VERSION); + onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, TRANSITION_DEFAULT, status, NO_VERSION); bool valid = false, has_assets = false; loadSkyWaterFromSettings(env_data, valid, has_assets); if (!has_assets && valid) diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 6ab0db7501..7cbf2d25bb 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -52,11 +52,11 @@ class LLEnvironment : public LLSingleton<LLEnvironment> LOG_CLASS(LLEnvironment); public: - static const F32Seconds TRANSITION_INSTANT; - static const F32Seconds TRANSITION_FAST; - static const F32Seconds TRANSITION_DEFAULT; - static const F32Seconds TRANSITION_SLOW; - static const F32Seconds TRANSITION_ALTITUDE; + static const F64Seconds TRANSITION_INSTANT; + static const F64Seconds TRANSITION_FAST; + static const F64Seconds TRANSITION_DEFAULT; + static const F64Seconds TRANSITION_SLOW; + static const F64Seconds TRANSITION_ALTITUDE; static const LLUUID KNOWN_SKY_SUNRISE; static const LLUUID KNOWN_SKY_MIDDAY; @@ -144,8 +144,8 @@ public: void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t()), env_version); } void setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed), env_version); } void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw), env_version); } - void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION); - void setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION); + void setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version); + void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, S32 env_version = NO_VERSION); void setSharedEnvironment(); void clearEnvironment(EnvSelection_t env); @@ -434,7 +434,7 @@ private: void onAgentPositionHasChanged(const LLVector3 &localpos); - void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status, S32 env_version); + void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsBase::Seconds transition, S32 status, S32 env_version); void onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, altitudes_vect_t altitudes); void handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 7a887a2549..83b5bf3f25 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -38,6 +38,7 @@ #include "lltooltip.h" #include "llagent.h" +#include "llagentpicksinfo.h" #include "llavatarnamecache.h" #include "llclipboard.h" #include "llinventorybridge.h" @@ -403,6 +404,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) mMoreTextBox = LLUICtrlFactory::create<LLTextBox> (more_button_params); mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this)); addChild(mMoreTextBox); + LLRect rect = mMoreTextBox->getRect(); + mMoreTextBox->setRect(LLRect(rect.mLeft - rect.getWidth(), rect.mTop, rect.mRight, rect.mBottom)); mDropDownItemsCount = 0; @@ -1202,6 +1205,10 @@ bool LLFavoritesBarCtrl::enableSelected(const LLSD& userdata) { return isClipboardPasteable(); } + else if (param == "create_pick") + { + return !LLAgentPicksInfo::getInstance()->isPickLimitReached(); + } return false; } @@ -1250,6 +1257,13 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) LLFloaterReg::showInstance("world_map", "center"); } } + else if (action == "create_pick") + { + LLSD args; + args["type"] = "create_pick"; + args["item_id"] = item->getUUID(); + LLFloaterSidePanelContainer::showPanel("places", args); + } else if (action == "cut") { } @@ -1265,6 +1279,20 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) { gInventory.removeItem(mSelectedItemID); } + else if (action == "rename") + { + LLSD args; + args["NAME"] = item->getName(); + + LLSD payload; + payload["id"] = mSelectedItemID; + + LLNotificationsUtil::add("RenameLandmark", args, payload, boost::bind(onRenameCommit, _1, _2)); + } + else if (action == "move_to_landmarks") + { + change_item_parent(mSelectedItemID, gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK)); + } // Pop-up the overflow menu again (it gets hidden whenever the user clicks a context menu item). // See EXT-4217 and STORM-207. @@ -1277,6 +1305,28 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) } } +bool LLFavoritesBarCtrl::onRenameCommit(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + LLUUID id = notification["payload"]["id"].asUUID(); + LLInventoryItem *item = gInventory.getItem(id); + std::string landmark_name = response["new_name"].asString(); + LLStringUtil::trim(landmark_name); + + if (!landmark_name.empty() && item && item->getName() != landmark_name) + { + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + new_item->rename(landmark_name); + new_item->updateServer(FALSE); + gInventory.updateItem(new_item); + } + } + + return false; +} + BOOL LLFavoritesBarCtrl::isClipboardPasteable() const { if (!LLClipboard::instance().hasContents()) diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 868f1c83c8..3bb940948b 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -91,6 +91,7 @@ protected: bool enableSelected(const LLSD& userdata); void doToSelected(const LLSD& userdata); + static bool onRenameCommit(const LLSD& notification, const LLSD& response); BOOL isClipboardPasteable() const; void pasteFromClipboard() const; diff --git a/indra/newview/llfloateraddpaymentmethod.cpp b/indra/newview/llfloateraddpaymentmethod.cpp new file mode 100644 index 0000000000..3952b48229 --- /dev/null +++ b/indra/newview/llfloateraddpaymentmethod.cpp @@ -0,0 +1,81 @@ +/** + * @file llfloateraddpaymentmethod.cpp + * @brief LLFloaterAddPaymentMethod class implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloateraddpaymentmethod.h" +#include "llnotificationsutil.h" +#include "lluictrlfactory.h" +#include "llweb.h" + + +LLFloaterAddPaymentMethod::LLFloaterAddPaymentMethod(const LLSD& key) + : LLFloater(key) +{ +} + +LLFloaterAddPaymentMethod::~LLFloaterAddPaymentMethod() +{ +} + +BOOL LLFloaterAddPaymentMethod::postBuild() +{ + setCanDrag(FALSE); + getChild<LLButton>("continue_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onContinueBtn, this)); + getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onCloseBtn, this)); + return TRUE; +} + +void LLFloaterAddPaymentMethod::onOpen(const LLSD& key) +{ + centerOnScreen(); +} + +void LLFloaterAddPaymentMethod::onContinueBtn() +{ + closeFloater(); + LLNotificationsUtil::add("AddPaymentMethod", LLSD(), LLSD(), + [this](const LLSD¬if, const LLSD&resp) + { + S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); + if (opt == 0) + { + LLWeb::loadURL(this->getString("continue_url")); + } + }); +} + +void LLFloaterAddPaymentMethod::onCloseBtn() +{ + closeFloater(); +} + +void LLFloaterAddPaymentMethod::centerOnScreen() +{ + LLVector2 window_size = LLUI::getInstance()->getWindowSize(); + centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY]))); +} + diff --git a/indra/newview/llfloateraddpaymentmethod.h b/indra/newview/llfloateraddpaymentmethod.h new file mode 100644 index 0000000000..b3bb624484 --- /dev/null +++ b/indra/newview/llfloateraddpaymentmethod.h @@ -0,0 +1,52 @@ +/** + * @file llfloateraddpaymentmethod.h + * @brief LLFloaterAddPaymentMethod class definition + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_FLOATER_ADDPAYMENTMETHOD_H +#define LL_FLOATER_ADDPAYMENTMETHOD_H + +#include "llfloater.h" + +class LLFloaterAddPaymentMethod: + public LLFloater +{ + friend class LLFloaterReg; +public: + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + +private: + LLFloaterAddPaymentMethod(const LLSD& key); + + void centerOnScreen(); + + void onCloseBtn(); + void onContinueBtn(); + + /*virtual*/ ~LLFloaterAddPaymentMethod(); + +}; + +#endif diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp index 1751d54b5a..0cfac166c7 100644 --- a/indra/newview/llfloaterbuycurrency.cpp +++ b/indra/newview/llfloaterbuycurrency.cpp @@ -32,6 +32,8 @@ #include "llcurrencyuimanager.h" #include "llfloater.h" #include "llfloaterreg.h" +#include "lllayoutstack.h" +#include "lliconctrl.h" #include "llnotificationsutil.h" #include "llstatusbar.h" #include "lltextbox.h" @@ -42,7 +44,6 @@ #include "llwindow.h" #include "llappviewer.h" -static const S32 STANDARD_BUY_AMOUNT = 2000; static const S32 MINIMUM_BALANCE_AMOUNT = 0; class LLFloaterBuyCurrencyUI @@ -58,8 +59,8 @@ public: LLCurrencyUIManager mManager; bool mHasTarget; - std::string mTargetName; S32 mTargetPrice; + S32 mRequiredAmount; public: void noTarget(); @@ -68,6 +69,7 @@ public: virtual BOOL postBuild(); void updateUI(); + void collapsePanels(bool collapse); virtual void draw(); virtual BOOL canClose(); @@ -92,7 +94,9 @@ LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key) LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI(const LLSD& key) : LLFloater(key), mChildren(*this), - mManager(*this) + mManager(*this), + mHasTarget(false), + mTargetPrice(0) { } @@ -104,15 +108,20 @@ LLFloaterBuyCurrencyUI::~LLFloaterBuyCurrencyUI() void LLFloaterBuyCurrencyUI::noTarget() { mHasTarget = false; - mManager.setAmount(STANDARD_BUY_AMOUNT); + mTargetPrice = 0; + mManager.setAmount(0); } void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price) { mHasTarget = true; - mTargetName = name; mTargetPrice = price; + if (!name.empty()) + { + getChild<LLUICtrl>("target_price_label")->setValue(name); + } + S32 balance = gStatusBar->getBalance(); S32 need = price - balance; if (need < 0) @@ -120,7 +129,8 @@ void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price) need = 0; } - mManager.setAmount(need + MINIMUM_BALANCE_AMOUNT); + mRequiredAmount = need + MINIMUM_BALANCE_AMOUNT; + mManager.setAmount(0); } @@ -175,7 +185,6 @@ void LLFloaterBuyCurrencyUI::updateUI() getChildView("purchase_warning_repurchase")->setVisible(FALSE); getChildView("purchase_warning_notenough")->setVisible(FALSE); getChildView("contacting")->setVisible(FALSE); - getChildView("buy_action")->setVisible(FALSE); if (hasError) { @@ -209,8 +218,8 @@ void LLFloaterBuyCurrencyUI::updateUI() { if (mHasTarget) { - getChildView("buy_action")->setVisible( true); - getChild<LLUICtrl>("buy_action")->setTextArg("[ACTION]", mTargetName); + getChild<LLUICtrl>("target_price")->setTextArg("[AMT]", llformat("%d", mTargetPrice)); + getChild<LLUICtrl>("required_amount")->setTextArg("[AMT]", llformat("%d", mRequiredAmount)); } } @@ -231,18 +240,40 @@ void LLFloaterBuyCurrencyUI::updateUI() if (mHasTarget) { - if (total >= mTargetPrice) - { - getChildView("purchase_warning_repurchase")->setVisible( true); - } - else - { - getChildView("purchase_warning_notenough")->setVisible( true); - } + getChildView("purchase_warning_repurchase")->setVisible( !getChildView("currency_links")->getVisible()); } } - getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError); + getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError && !getChildView("currency_est")->getVisible()); +} + +void LLFloaterBuyCurrencyUI::collapsePanels(bool collapse) +{ + LLLayoutPanel* price_panel = getChild<LLLayoutPanel>("layout_panel_price"); + + if (price_panel->isCollapsed() == collapse) + return; + + LLLayoutStack* outer_stack = getChild<LLLayoutStack>("outer_stack"); + LLLayoutPanel* required_panel = getChild<LLLayoutPanel>("layout_panel_required"); + LLLayoutPanel* msg_panel = getChild<LLLayoutPanel>("layout_panel_msg"); + + S32 delta_height = price_panel->getRect().getHeight() + required_panel->getRect().getHeight() + msg_panel->getRect().getHeight(); + delta_height *= (collapse ? -1 : 1); + + LLIconCtrl* icon = getChild<LLIconCtrl>("normal_background"); + LLRect rect = icon->getRect(); + icon->setRect(rect.setOriginAndSize(rect.mLeft, rect.mBottom - delta_height, rect.getWidth(), rect.getHeight() + delta_height)); + + outer_stack->collapsePanel(price_panel, collapse); + outer_stack->collapsePanel(required_panel, collapse); + outer_stack->collapsePanel(msg_panel, collapse); + + outer_stack->updateLayout(); + + LLRect floater_rect = getRect(); + floater_rect.mBottom -= delta_height; + setShape(floater_rect, false); } void LLFloaterBuyCurrencyUI::onClickBuy() @@ -260,20 +291,72 @@ void LLFloaterBuyCurrencyUI::onClickCancel() LLStatusBar::sendMoneyBalanceRequest(); } +LLFetchAvatarPaymentInfo* LLFloaterBuyCurrency::sPropertiesRequest = NULL; + // static void LLFloaterBuyCurrency::buyCurrency() { - LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency"); - ui->noTarget(); - ui->updateUI(); + delete sPropertiesRequest; + sPropertiesRequest = new LLFetchAvatarPaymentInfo(false); } // static void LLFloaterBuyCurrency::buyCurrency(const std::string& name, S32 price) { - LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency"); - ui->target(name, price); - ui->updateUI(); + delete sPropertiesRequest; + sPropertiesRequest = new LLFetchAvatarPaymentInfo(true, name, price); +} + +// static +void LLFloaterBuyCurrency::handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price) +{ + delete sPropertiesRequest; + sPropertiesRequest = NULL; + + if (has_piof) + { + LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency"); + if (has_target) + { + ui->target(name, price); + } + else + { + ui->noTarget(); + } + ui->updateUI(); + ui->collapsePanels(!has_target); + } + else + { + LLFloaterReg::showInstance("add_payment_method"); + } } +LLFetchAvatarPaymentInfo::LLFetchAvatarPaymentInfo(bool has_target, const std::string& name, S32 price) +: mAvatarID(gAgent.getID()), + mHasTarget(has_target), + mPrice(price), + mName(name) +{ + LLAvatarPropertiesProcessor* processor = LLAvatarPropertiesProcessor::getInstance(); + // register ourselves as an observer + processor->addObserver(mAvatarID, this); + // send a request (duplicates will be suppressed inside the avatar + // properties processor) + processor->sendAvatarPropertiesRequest(mAvatarID); +} + +LLFetchAvatarPaymentInfo::~LLFetchAvatarPaymentInfo() +{ + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarID, this); +} +void LLFetchAvatarPaymentInfo::processProperties(void* data, EAvatarProcessorType type) +{ + if (data && type == APT_PROPERTIES) + { + LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + LLFloaterBuyCurrency::handleBuyCurrency(LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(avatar_data), mHasTarget, mName, mPrice); + } +} diff --git a/indra/newview/llfloaterbuycurrency.h b/indra/newview/llfloaterbuycurrency.h index 7ff6c42384..88d3d17cd6 100644 --- a/indra/newview/llfloaterbuycurrency.h +++ b/indra/newview/llfloaterbuycurrency.h @@ -27,15 +27,34 @@ #ifndef LL_LLFLOATERBUYCURRENCY_H #define LL_LLFLOATERBUYCURRENCY_H +#include "llavatarpropertiesprocessor.h" #include "stdtypes.h" - +#include "llagent.h" class LLFloater; +class LLFetchAvatarPaymentInfo : public LLAvatarPropertiesObserver +{ +public: + LLFetchAvatarPaymentInfo(bool has_target, const std::string& name = std::string(), S32 price = 0); + ~LLFetchAvatarPaymentInfo(); + + void processProperties(void* data, EAvatarProcessorType type); + +private: + LLUUID mAvatarID; + bool mHasTarget; + std::string mName; + S32 mPrice; +}; + + class LLFloaterBuyCurrency { public: static void buyCurrency(); static void buyCurrency(const std::string& name, S32 price); + + static void handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price); /* name should be a noun phrase of the object or service being bought: "That object costs" "Trying to give" @@ -44,7 +63,8 @@ public: */ static LLFloater* buildFloater(const LLSD& key); -}; + static LLFetchAvatarPaymentInfo* sPropertiesRequest; +}; #endif diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp new file mode 100644 index 0000000000..eb93a6a75a --- /dev/null +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -0,0 +1,323 @@ +/** + * @file llfloatercreatelandmark.cpp + * @brief LLFloaterCreateLandmark class implementation + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatercreatelandmark.h" + +#include "llagent.h" +#include "llagentui.h" +#include "llcombobox.h" +#include "llinventoryfunctions.h" +#include "llinventoryobserver.h" +#include "lllandmarkactions.h" +#include "llnotificationsutil.h" +#include "llpanellandmarkinfo.h" +#include "llparcel.h" +#include "lltextbox.h" +#include "lltexteditor.h" +#include "lluictrlfactory.h" +#include "llviewermessage.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" + +typedef std::pair<LLUUID, std::string> folder_pair_t; + +class LLLandmarksInventoryObserver : public LLInventoryAddedObserver +{ +public: + LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) : + mFloater(create_landmark_floater) + {} + +protected: + /*virtual*/ void done() + { + mFloater->setItem(gInventory.getAddedIDs()); + } + +private: + LLFloaterCreateLandmark* mFloater; +}; + +LLFloaterCreateLandmark::LLFloaterCreateLandmark(const LLSD& key) + : LLFloater("add_landmark"), + mItem(NULL) +{ + mInventoryObserver = new LLLandmarksInventoryObserver(this); +} + +LLFloaterCreateLandmark::~LLFloaterCreateLandmark() +{ + removeObserver(); +} + +BOOL LLFloaterCreateLandmark::postBuild() +{ + mFolderCombo = getChild<LLComboBox>("folder_combo"); + mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor"); + mNotesEditor = getChild<LLTextEditor>("notes_editor"); + + getChild<LLTextBox>("new_folder_textbox")->setURLClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCreateFolderClicked, this)); + getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this)); + getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this)); + + mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); + + return TRUE; +} + +void LLFloaterCreateLandmark::removeObserver() +{ + if (gInventory.containsObserver(mInventoryObserver)) + gInventory.removeObserver(mInventoryObserver); +} + +void LLFloaterCreateLandmark::onOpen(const LLSD& key) +{ + LLUUID dest_folder = LLUUID(); + if (key.has("dest_folder")) + { + dest_folder = key["dest_folder"].asUUID(); + } + mItem = NULL; + gInventory.addObserver(mInventoryObserver); + setLandmarkInfo(dest_folder); + populateFoldersList(dest_folder); +} + +void LLFloaterCreateLandmark::setLandmarkInfo(const LLUUID &folder_id) +{ + LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); + LLParcel* parcel = parcel_mgr->getAgentParcel(); + std::string name = parcel->getName(); + LLVector3 agent_pos = gAgent.getPositionAgent(); + + if (name.empty()) + { + S32 region_x = ll_round(agent_pos.mV[VX]); + S32 region_y = ll_round(agent_pos.mV[VY]); + S32 region_z = ll_round(agent_pos.mV[VZ]); + + std::string region_name; + LLViewerRegion* region = parcel_mgr->getSelectionRegion(); + if (region) + { + region_name = region->getName(); + } + else + { + std::string desc; + LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos); + region_name = desc; + } + + mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)", + region_name.c_str(), region_x, region_y, region_z)); + } + else + { + mLandmarkTitleEditor->setText(name); + } + + LLLandmarkActions::createLandmarkHere(name, "", folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)); +} + +bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) +{ + return left.second < right.second; +} + +void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id) +{ + // Collect all folders that can contain landmarks. + LLInventoryModel::cat_array_t cats; + LLPanelLandmarkInfo::collectLandmarkFolders(cats); + + mFolderCombo->removeall(); + + // Put the "My Favorites" folder first in list. + LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id); + if (!favorites_cat) + { + LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL; + } + else + { + mFolderCombo->add(getString("favorites_bar"), favorites_cat->getUUID()); + } + + // Add the "Landmarks" category. + const LLViewerInventoryCategory* lmcat = gInventory.getCategory(mLandmarksID); + if (!lmcat) + { + LL_WARNS() << "Cannot find the landmarks folder" << LL_ENDL; + } + else + { + std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(lmcat); + mFolderCombo->add(cat_full_name, lmcat->getUUID()); + } + + typedef std::vector<folder_pair_t> folder_vec_t; + folder_vec_t folders; + // Sort the folders by their full name. + for (S32 i = 0; i < cats.size(); i++) + { + const LLViewerInventoryCategory* cat = cats.at(i); + std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(cat); + folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name)); + } + sort(folders.begin(), folders.end(), cmp_folders); + + // Finally, populate the combobox. + for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++) + mFolderCombo->add(it->second, LLSD(it->first)); + + if (folder_id.notNull()) + { + mFolderCombo->setCurrentByID(folder_id); + } +} + +void LLFloaterCreateLandmark::onCreateFolderClicked() +{ + LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(), + [this](const LLSD¬if, const LLSD&resp) + { + S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); + if (opt == 0) + { + std::string folder_name = resp["message"].asString(); + if (!folder_name.empty()) + { + inventory_func_type func = boost::bind(&LLFloaterCreateLandmark::folderCreatedCallback, this, _1); + gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, func); + gInventory.notifyObservers(); + } + } + }); +} + +void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id) +{ + populateFoldersList(folder_id); +} + +void LLFloaterCreateLandmark::onSaveClicked() +{ + if (mItem.isNull()) + { + closeFloater(); + return; + } + + + std::string current_title_value = mLandmarkTitleEditor->getText(); + std::string item_title_value = mItem->getName(); + std::string current_notes_value = mNotesEditor->getText(); + std::string item_notes_value = mItem->getDescription(); + + LLStringUtil::trim(current_title_value); + LLStringUtil::trim(current_notes_value); + + LLUUID item_id = mItem->getUUID(); + LLUUID folder_id = mFolderCombo->getValue().asUUID(); + bool change_parent = folder_id != mItem->getParentUUID(); + + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem); + + if (!current_title_value.empty() && + (item_title_value != current_title_value || item_notes_value != current_notes_value)) + { + new_item->rename(current_title_value); + new_item->setDescription(current_notes_value); + LLPointer<LLInventoryCallback> cb; + if (change_parent) + { + cb = new LLUpdateLandmarkParent(new_item, folder_id); + } + LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); + gInventory.accountForUpdate(up); + update_inventory_item(new_item, cb); + } + else if (change_parent) + { + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); + + new_item->setParent(folder_id); + new_item->updateParentOnServer(FALSE); + } + + gInventory.updateItem(new_item); + gInventory.notifyObservers(); + + closeFloater(); +} + +void LLFloaterCreateLandmark::onCancelClicked() +{ + if (!mItem.isNull()) + { + LLUUID item_id = mItem->getUUID(); + remove_inventory_item(item_id, NULL); + } + closeFloater(); +} + + +void LLFloaterCreateLandmark::setItem(const uuid_set_t& items) +{ + for (uuid_set_t::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) + { + const LLUUID& item_id = (*item_iter); + if(!highlight_offered_object(item_id)) + { + continue; + } + + LLInventoryItem* item = gInventory.getItem(item_id); + + llassert(item); + if (item && (LLAssetType::AT_LANDMARK == item->getType()) ) + { + if(!getItem()) + { + removeObserver(); + mItem = item; + break; + } + } + } +}
\ No newline at end of file diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h new file mode 100644 index 0000000000..74ac5e651c --- /dev/null +++ b/indra/newview/llfloatercreatelandmark.h @@ -0,0 +1,74 @@ +/** + * @file llfloatercreatelandmark.h + * @brief LLFloaterCreateLandmark class definition + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERCREATELANDMARK_H +#define LL_LLFLOATERCREATELANDMARK_H + +#include "llfloater.h" + +class LLComboBox; +class LLInventoryItem; +class LLLineEditor; +class LLTextEditor; +class LLLandmarksInventoryObserver; + +class LLFloaterCreateLandmark: + public LLFloater +{ + friend class LLFloaterReg; + +public: + + LLFloaterCreateLandmark(const LLSD& key); + ~LLFloaterCreateLandmark(); + + BOOL postBuild(); + void onOpen(const LLSD& key); + + void setItem(const uuid_set_t& items); + + LLInventoryItem* getItem() { return mItem; } + +private: + void setLandmarkInfo(const LLUUID &folder_id); + void removeObserver(); + void populateFoldersList(const LLUUID &folder_id = LLUUID::null); + void onCreateFolderClicked(); + void onSaveClicked(); + void onCancelClicked(); + + void folderCreatedCallback(LLUUID folder_id); + + LLComboBox* mFolderCombo; + LLLineEditor* mLandmarkTitleEditor; + LLTextEditor* mNotesEditor; + LLUUID mLandmarksID; + + LLLandmarksInventoryObserver* mInventoryObserver; + LLPointer<LLInventoryItem> mItem; +}; + +#endif diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp index 4eb5e03603..95d6a2d652 100644 --- a/indra/newview/llfloaterenvironmentadjust.cpp +++ b/indra/newview/llfloaterenvironmentadjust.cpp @@ -53,11 +53,15 @@ namespace const std::string FIELD_SKY_CLOUD_SCALE("cloud_scale"); const std::string FIELD_SKY_SCENE_GAMMA("scene_gamma"); const std::string FIELD_SKY_SUN_ROTATION("sun_rotation"); + const std::string FIELD_SKY_SUN_AZIMUTH("sun_azimuth"); + const std::string FIELD_SKY_SUN_ELEVATION("sun_elevation"); const std::string FIELD_SKY_SUN_SCALE("sun_scale"); const std::string FIELD_SKY_GLOW_FOCUS("glow_focus"); const std::string FIELD_SKY_GLOW_SIZE("glow_size"); const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness"); const std::string FIELD_SKY_MOON_ROTATION("moon_rotation"); + const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth"); + const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation"); const std::string BTN_RESET("btn_reset"); const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f); @@ -96,9 +100,13 @@ BOOL LLFloaterEnvironmentAdjust::postBuild() getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); }); getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); }); getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); }); getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); }); getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); }); getChild<LLUICtrl>(BTN_RESET)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onButtonReset(); }); getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudMapChanged(); }); @@ -169,10 +177,25 @@ void LLFloaterEnvironmentAdjust::refresh() getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setValue(2.0 - (glow.mV[0] / SLIDER_SCALE_GLOW_R)); getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B); getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mLiveSky->getStarBrightness()); - getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mLiveSky->getSunRotation()); getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mLiveSky->getSunScale()); - getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mLiveSky->getMoonRotation()); + // Sun rotation + LLQuaternion quat = mLiveSky->getSunRotation(); + F32 azimuth; + F32 elevation; + LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + + getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth); + getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation); + getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat); + + // Moon rotation + quat = mLiveSky->getMoonRotation(); + LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + + getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth); + getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation); + getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat); } @@ -325,10 +348,45 @@ void LLFloaterEnvironmentAdjust::onStarBrightnessChanged() void LLFloaterEnvironmentAdjust::onSunRotationChanged() { - if (!mLiveSky) - return; - mLiveSky->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation()); - mLiveSky->update(); + LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation(); + F32 azimuth; + F32 elevation; + LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth); + getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation); + if (mLiveSky) + { + mLiveSky->setSunRotation(quat); + mLiveSky->update(); + } +} + +void LLFloaterEnvironmentAdjust::onSunAzimElevChanged() +{ + F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal(); + F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal(); + LLQuaternion quat; + + azimuth *= DEG_TO_RAD; + elevation *= DEG_TO_RAD; + + if (is_approx_zero(elevation)) + { + elevation = F_APPROXIMATELY_ZERO; + } + + quat.setAngleAxis(-elevation, 0, 1, 0); + LLQuaternion az_quat; + az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1); + quat *= az_quat; + + getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat); + + if (mLiveSky) + { + mLiveSky->setSunRotation(quat); + mLiveSky->update(); + } } void LLFloaterEnvironmentAdjust::onSunScaleChanged() @@ -341,10 +399,45 @@ void LLFloaterEnvironmentAdjust::onSunScaleChanged() void LLFloaterEnvironmentAdjust::onMoonRotationChanged() { - if (!mLiveSky) - return; - mLiveSky->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation()); - mLiveSky->update(); + LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation(); + F32 azimuth; + F32 elevation; + LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth); + getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation); + if (mLiveSky) + { + mLiveSky->setMoonRotation(quat); + mLiveSky->update(); + } +} + +void LLFloaterEnvironmentAdjust::onMoonAzimElevChanged() +{ + F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal(); + F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal(); + LLQuaternion quat; + + azimuth *= DEG_TO_RAD; + elevation *= DEG_TO_RAD; + + if (is_approx_zero(elevation)) + { + elevation = F_APPROXIMATELY_ZERO; + } + + quat.setAngleAxis(-elevation, 0, 1, 0); + LLQuaternion az_quat; + az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1); + quat *= az_quat; + + getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat); + + if (mLiveSky) + { + mLiveSky->setMoonRotation(quat); + mLiveSky->update(); + } } void LLFloaterEnvironmentAdjust::onCloudMapChanged() diff --git a/indra/newview/llfloaterenvironmentadjust.h b/indra/newview/llfloaterenvironmentadjust.h index cb38dbcfa8..05ff011be5 100644 --- a/indra/newview/llfloaterenvironmentadjust.h +++ b/indra/newview/llfloaterenvironmentadjust.h @@ -73,9 +73,11 @@ private: void onGlowChanged(); void onStarBrightnessChanged(); void onSunRotationChanged(); + void onSunAzimElevChanged(); void onSunScaleChanged(); void onMoonRotationChanged(); + void onMoonAzimElevChanged(); void onCloudMapChanged(); void onWaterMapChanged(); diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index 41bbd5e8f9..4f2c36f45b 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -128,7 +128,7 @@ void LLFloaterFixedEnvironment::onOpen(const LLSD& key) updateEditEnvironment(); syncronizeTabs(); refresh(); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT); } @@ -180,7 +180,7 @@ void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::p updateEditEnvironment(); syncronizeTabs(); refresh(); - LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); } void LLFloaterFixedEnvironment::syncronizeTabs() @@ -460,7 +460,7 @@ void LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile(const std::vector< setDirtyFlag(); LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacywater); setEditSettings(legacywater); - LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true); } //========================================================================= @@ -548,7 +548,7 @@ void LLFloaterFixedEnvironmentSky::loadSkySettingFromFile(const std::vector<std: setDirtyFlag(); LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacysky); setEditSettings(legacysky); - LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true); } //========================================================================= diff --git a/indra/newview/llfloaterhandler.cpp b/indra/newview/llfloaterhandler.cpp index e2160498e9..8ebb14149c 100644 --- a/indra/newview/llfloaterhandler.cpp +++ b/indra/newview/llfloaterhandler.cpp @@ -26,6 +26,7 @@ #include "llfloater.h" #include "llmediactrl.h" +#include "llfloaterreg.h" // register with dispatch via global object LLFloaterHandler gFloaterHandler; @@ -50,9 +51,15 @@ LLFloater* get_parent_floater(LLView* view) bool LLFloaterHandler::handle(const LLSD ¶ms, const LLSD &query_map, LLMediaCtrl *web) { - if (params.size() < 2) return false; + if (params.size() < 1) return false; LLFloater* floater = NULL; // *TODO: implement floater lookup by name + + if (params[0].asString() == "destinations") + { + LLFloaterReg::toggleInstanceOrBringToFront("destinations"); + return true; + } if (params[0].asString() == "self") { if (web) diff --git a/indra/newview/llfloaterhowto.cpp b/indra/newview/llfloaterhowto.cpp new file mode 100644 index 0000000000..a359fb7c7d --- /dev/null +++ b/indra/newview/llfloaterhowto.cpp @@ -0,0 +1,92 @@ +/** + * @file llfloaterhowto.cpp + * @brief A variant of web floater meant to open guidebook + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterhowto.h" + +#include "llfloaterreg.h" +#include "llviewercontrol.h" +#include "llweb.h" + + +const S32 STACK_WIDTH = 300; +const S32 STACK_HEIGHT = 505; // content will be 500 + +LLFloaterHowTo::LLFloaterHowTo(const Params& key) : + LLFloaterWebContent(key) +{ + mShowPageTitle = false; +} + +BOOL LLFloaterHowTo::postBuild() +{ + LLFloaterWebContent::postBuild(); + + return TRUE; +} + +void LLFloaterHowTo::onOpen(const LLSD& key) +{ + LLFloaterWebContent::Params p(key); + if (!p.url.isProvided() || p.url.getValue().empty()) + { + std::string url = gSavedSettings.getString("GuidebookURL"); + p.url = LLWeb::expandURLSubstitutions(url, LLSD()); + } + p.show_chrome = false; + + LLFloaterWebContent::onOpen(p); + + if (p.preferred_media_size().isEmpty()) + { + // Elements from LLFloaterWebContent did not pick up restored size (save_rect) of LLFloaterHowTo + // set the stack size and position (alternative to preferred_media_size) + LLLayoutStack *stack = getChild<LLLayoutStack>("stack1"); + LLRect stack_rect = stack->getRect(); + stack->reshape(STACK_WIDTH, STACK_HEIGHT); + stack->setOrigin(stack_rect.mLeft, stack_rect.mTop - STACK_HEIGHT); + stack->updateLayout(); + } +} + +LLFloaterHowTo* LLFloaterHowTo::getInstance() +{ + return LLFloaterReg::getTypedInstance<LLFloaterHowTo>("guidebook"); +} + +BOOL LLFloaterHowTo::handleKeyHere(KEY key, MASK mask) +{ + BOOL handled = FALSE; + + if (KEY_F1 == key ) + { + closeFloater(); + handled = TRUE; + } + + return handled; +} diff --git a/indra/newview/llfloaterhowto.h b/indra/newview/llfloaterhowto.h new file mode 100644 index 0000000000..d8da355600 --- /dev/null +++ b/indra/newview/llfloaterhowto.h @@ -0,0 +1,58 @@ +/** + * @file llfloaterhowto.h + * @brief A variant of web floater meant to open guidebook + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERHOWTO_H +#define LL_LLFLOATERHOWTO_H + +#include "llfloaterwebcontent.h" + +class LLMediaCtrl; + + +class LLFloaterHowTo : + public LLFloaterWebContent +{ +public: + LOG_CLASS(LLFloaterHowTo); + + typedef LLFloaterWebContent::Params Params; + + LLFloaterHowTo(const Params& key); + + void onOpen(const LLSD& key) override; + + BOOL handleKeyHere(KEY key, MASK mask) override; + + static LLFloaterHowTo* getInstance(); + + bool matchesKey(const LLSD& key) override { return true; /*single instance*/ }; + +private: + BOOL postBuild() override; +}; + +#endif // LL_LLFLOATERHOWTO_H + diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index a6531ed7e1..3a850d4b68 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -67,6 +67,7 @@ #include "llviewerchat.h" #include "lltranslate.h" #include "llautoreplace.h" +#include "lluiusage.h" S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0; @@ -697,6 +698,7 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, ECha void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) { + LLUIUsage::instance().logCommand("Chat.Send"); // pseuo-command // Look for "/20 foo" channel chats. S32 channel = 0; LLWString out_text = stripChannelNumber(wtext, &channel); diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index f34760a6bf..749a3d2686 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -51,6 +51,9 @@ #include "llgroupactions.h" +const std::string LINDEN_HOMES_SKU = "131"; +bool LLFloaterLandHoldings::sHasLindenHome = false; + // protected LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key) : LLFloater(key), @@ -148,10 +151,24 @@ void LLFloaterLandHoldings::refresh() void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**) { LLFloaterLandHoldings* self = LLFloaterReg::findTypedInstance<LLFloaterLandHoldings>("land_holdings"); - - // Is this packet from an old, closed window? + S32 count = msg->getNumberOfBlocks("QueryData"); + std::string land_sku; + sHasLindenHome = false; if (!self) { + for (S32 i = 0; i < count; i++) + { + if ( msg->getSizeFast(_PREHASH_QueryData, i, _PREHASH_ProductSKU) > 0 ) + { + msg->getStringFast( _PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i); + + if (LINDEN_HOMES_SKU == land_sku) + { + sHasLindenHome = true; + return; + } + } + } return; } @@ -174,12 +191,9 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**) F32 global_x; F32 global_y; std::string sim_name; - std::string land_sku; std::string land_type; - S32 i; - S32 count = msg->getNumberOfBlocks("QueryData"); - for (i = 0; i < count; i++) + for (S32 i = 0; i < count; i++) { msg->getUUID("QueryData", "OwnerID", owner_id, i); msg->getString("QueryData", "Name", name, i); @@ -196,6 +210,10 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**) msg->getStringFast( _PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i); LL_INFOS() << "Land sku: " << land_sku << LL_ENDL; land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku); + if (LINDEN_HOMES_SKU == land_sku) + { + sHasLindenHome = true; + } } else { diff --git a/indra/newview/llfloaterlandholdings.h b/indra/newview/llfloaterlandholdings.h index d1d510bb40..90e75b1062 100644 --- a/indra/newview/llfloaterlandholdings.h +++ b/indra/newview/llfloaterlandholdings.h @@ -57,6 +57,8 @@ public: static void onGrantList(void* data); + static bool sHasLindenHome; + protected: void refreshAggregates(); diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index 06a908cccc..51b98339c4 100644 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -45,6 +45,7 @@ public: virtual LLFolderType::EType getPreferredType() const = 0; virtual void showProperties(void) = 0; virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual. + virtual BOOL isAgentInventory() const { return FALSE; } virtual BOOL isUpToDate() const = 0; virtual bool hasChildren() const = 0; virtual LLInventoryType::EType getInventoryType() const = 0; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d35d8456be..8b61e6c61a 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1835,28 +1835,11 @@ void LLItemBridge::restoreToWorld() void LLItemBridge::gotoItem() { - LLInventoryObject *obj = getInventoryObject(); - if (obj && obj->getIsLinkType()) - { - const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); - if (gInventory.isObjectDescendentOf(obj->getLinkedUUID(), inbox_id)) - { - LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - if (sidepanel_inventory && sidepanel_inventory->getInboxPanel()) - { - sidepanel_inventory->getInboxPanel()->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO); - } - } - else - { - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); - if (active_panel) - { - active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO); - } - } - - } + LLInventoryObject *obj = getInventoryObject(); + if (obj && obj->getIsLinkType()) + { + show_item_original(obj->getUUID()); + } } LLUIImagePtr LLItemBridge::getIcon() const @@ -4101,6 +4084,12 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items items.push_back(std::string("New Body Parts")); items.push_back(std::string("New Settings")); items.push_back(std::string("upload_def")); + + if (!LLEnvironment::instance().isInventoryEnabled()) + { + disabled_items.push_back("New Settings"); + } + } } getClipboardEntries(false, items, disabled_items, flags); @@ -7037,8 +7026,8 @@ void LLSettingsBridge::performAction(LLInventoryModel* model, std::string action if (!item) return; LLUUID asset_id = item->getAssetUUID(); - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id, LLEnvironment::TRANSITION_INSTANT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); } else if ("apply_settings_parcel" == action) { @@ -7212,21 +7201,17 @@ void LLLinkFolderBridge::performAction(LLInventoryModel* model, std::string acti } void LLLinkFolderBridge::gotoItem() { - const LLUUID &cat_uuid = getFolderID(); - if (!cat_uuid.isNull()) - { - LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid); - if (base_folder) - { - if (LLInventoryModel* model = getInventoryModel()) - { - model->fetchDescendentsOf(cat_uuid); - } - base_folder->setOpen(TRUE); - mRoot->setSelection(base_folder,TRUE); - mRoot->scrollToShowSelection(); - } - } + LLItemBridge::gotoItem(); + + const LLUUID &cat_uuid = getFolderID(); + if (!cat_uuid.isNull()) + { + LLFolderViewItem *base_folder = LLInventoryPanel::getActiveInventoryPanel()->getItemByID(cat_uuid); + if (base_folder) + { + base_folder->setOpen(TRUE); + } + } } const LLUUID &LLLinkFolderBridge::getFolderID() const { diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 2a22eb1329..411311bbea 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -63,7 +63,8 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p) mPermissions(p.permissions), mFilterTypes(p.types), mFilterUUID(p.uuid), - mFilterLinks(p.links) + mFilterLinks(p.links), + mSearchVisibility(p.search_visibility) { } @@ -155,6 +156,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item) passed = passed && checkAgainstPermissions(listener); passed = passed && checkAgainstFilterLinks(listener); passed = passed && checkAgainstCreator(listener); + passed = passed && checkAgainstSearchVisibility(listener); return passed; } @@ -583,6 +585,27 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory } } +bool LLInventoryFilter::checkAgainstSearchVisibility(const LLFolderViewModelItemInventory* listener) const +{ + if (!listener || !hasFilterString()) return TRUE; + + const LLUUID object_id = listener->getUUID(); + const LLInventoryObject *object = gInventory.getObject(object_id); + if (!object) return TRUE; + + const BOOL is_link = object->getIsLinkType(); + if (is_link && ((mFilterOps.mSearchVisibility & VISIBILITY_LINKS) == 0)) + return FALSE; + + if (listener->isItemInTrash() && ((mFilterOps.mSearchVisibility & VISIBILITY_TRASH) == 0)) + return FALSE; + + if (!listener->isAgentInventory() && ((mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY) == 0)) + return FALSE; + + return TRUE; +} + const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const { return mFilterSubString; @@ -751,6 +774,61 @@ void LLInventoryFilter::setFilterMarketplaceListingFolders(bool select_only_list } } + +void LLInventoryFilter::toggleSearchVisibilityLinks() +{ + bool hide_links = mFilterOps.mSearchVisibility & VISIBILITY_LINKS; + if (hide_links) + { + mFilterOps.mSearchVisibility &= ~VISIBILITY_LINKS; + } + else + { + mFilterOps.mSearchVisibility |= VISIBILITY_LINKS; + } + + if (hasFilterString()) + { + setModified(hide_links ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE); + } +} + +void LLInventoryFilter::toggleSearchVisibilityTrash() +{ + bool hide_trash = mFilterOps.mSearchVisibility & VISIBILITY_TRASH; + if (hide_trash) + { + mFilterOps.mSearchVisibility &= ~VISIBILITY_TRASH; + } + else + { + mFilterOps.mSearchVisibility |= VISIBILITY_TRASH; + } + + if (hasFilterString()) + { + setModified(hide_trash ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE); + } +} + +void LLInventoryFilter::toggleSearchVisibilityLibrary() +{ + bool hide_library = mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY; + if (hide_library) + { + mFilterOps.mSearchVisibility &= ~VISIBILITY_LIBRARY; + } + else + { + mFilterOps.mSearchVisibility |= VISIBILITY_LIBRARY; + } + + if (hasFilterString()) + { + setModified(hide_library ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE); + } +} + void LLInventoryFilter::setFilterNoMarketplaceFolder() { mFilterOps.mFilterTypes |= FILTERTYPE_NO_MARKETPLACE_ITEMS; @@ -862,6 +940,44 @@ void LLInventoryFilter::setFilterSubString(const std::string& string) } } +void LLInventoryFilter::setSearchVisibilityTypes(U32 types) +{ + if (mFilterOps.mSearchVisibility != types) + { + // keep current items only if no perm bits getting turned off + BOOL fewer_bits_set = (mFilterOps.mSearchVisibility & ~types); + BOOL more_bits_set = (~mFilterOps.mSearchVisibility & types); + mFilterOps.mSearchVisibility = types; + + if (more_bits_set && fewer_bits_set) + { + setModified(FILTER_RESTART); + } + else if (more_bits_set) + { + // target must have all requested permission bits, so more bits == more restrictive + setModified(FILTER_MORE_RESTRICTIVE); + } + else if (fewer_bits_set) + { + setModified(FILTER_LESS_RESTRICTIVE); + } + } +} + +void LLInventoryFilter::setSearchVisibilityTypes(const Params& params) +{ + if (!params.validateBlock()) + { + return; + } + + if (params.filter_ops.search_visibility.isProvided()) + { + setSearchVisibilityTypes(params.filter_ops.search_visibility); + } +} + void LLInventoryFilter::setFilterPermissions(PermissionMask perms) { if (mFilterOps.mPermissions != perms) @@ -1263,6 +1379,18 @@ const std::string& LLInventoryFilter::getFilterText() filtered_by_all_types = FALSE; } + if (isFilterObjectTypesWith(LLInventoryType::IT_SETTINGS)) + { + filtered_types += LLTrans::getString("Settings"); + filtered_by_type = TRUE; + num_filter_types++; + } + else + { + not_filtered_types += LLTrans::getString("Settings"); + filtered_by_all_types = FALSE; + } + if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() && filtered_by_type && !filtered_by_all_types) @@ -1318,6 +1446,7 @@ void LLInventoryFilter::toParams(Params& params) const params.filter_ops.show_folder_state = getShowFolderState(); params.filter_ops.creator_type = getFilterCreatorType(); params.filter_ops.permissions = getFilterPermissions(); + params.filter_ops.search_visibility = getSearchVisibilityTypes(); params.substring = getFilterSubString(); params.since_logoff = isSinceLogoff(); } @@ -1341,6 +1470,7 @@ void LLInventoryFilter::fromParams(const Params& params) setShowFolderState(params.filter_ops.show_folder_state); setFilterCreator(params.filter_ops.creator_type); setFilterPermissions(params.filter_ops.permissions); + setSearchVisibilityTypes(params.filter_ops.search_visibility); setFilterSubString(params.substring); setDateRangeLastLogoff(params.since_logoff); } @@ -1370,6 +1500,11 @@ U64 LLInventoryFilter::getFilterSettingsTypes() const return mFilterOps.mFilterSettingsTypes; } +U64 LLInventoryFilter::getSearchVisibilityTypes() const +{ + return mFilterOps.mSearchVisibility; +} + bool LLInventoryFilter::hasFilterString() const { return mFilterSubString.size() > 0; diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 61cc5ae602..384de3e889 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -99,6 +99,14 @@ public: FILTERCREATOR_OTHERS }; + enum ESearchVisibility + { + VISIBILITY_NONE = 0, + VISIBILITY_TRASH = 0x1 << 0, + VISIBILITY_LIBRARY = 0x1 << 1, + VISIBILITY_LINKS = 0x1 << 2 + }; + struct FilterOps { struct DateRange : public LLInitParam::Block<DateRange> @@ -116,11 +124,13 @@ public: struct Params : public LLInitParam::Block<Params> { - Optional<U32> types; + Optional<U32> types, + search_visibility; Optional<U64> object_types, wearable_types, settings_types, category_types; + Optional<EFilterLink> links; Optional<LLUUID> uuid; Optional<DateRange> date_range; @@ -137,6 +147,7 @@ public: settings_types("settings_types", 0xffffFFFFffffFFFFULL), category_types("category_types", 0xffffFFFFffffFFFFULL), links("links", FILTERLINK_INCLUDE_LINKS), + search_visibility("search_visibility", 0xFFFFFFFF), uuid("uuid"), date_range("date_range"), hours_ago("hours_ago", 0), @@ -149,7 +160,8 @@ public: FilterOps(const Params& = Params()); - U32 mFilterTypes; + U32 mFilterTypes, + mSearchVisibility; U64 mFilterObjectTypes, // For _OBJECT mFilterWearableTypes, mFilterSettingsTypes, // for _SETTINGS @@ -193,7 +205,8 @@ public: U64 getFilterObjectTypes() const; U64 getFilterCategoryTypes() const; U64 getFilterWearableTypes() const; - U64 getFilterSettingsTypes() const; + U64 getFilterSettingsTypes() const; + U64 getSearchVisibilityTypes() const; bool isFilterObjectTypesWith(LLInventoryType::EType t) const; void setFilterObjectTypes(U64 types); @@ -213,6 +226,12 @@ public: ESearchType getSearchType() { return mSearchType; } void setFilterCreator(EFilterCreatorType type); + void toggleSearchVisibilityLinks(); + void toggleSearchVisibilityTrash(); + void toggleSearchVisibilityLibrary(); + void setSearchVisibilityTypes(U32 types); + void setSearchVisibilityTypes(const Params& params); + void setFilterSubString(const std::string& string); const std::string& getFilterSubString(BOOL trim = FALSE) const; const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; } @@ -310,6 +329,7 @@ private: bool checkAgainstPermissions(const LLInventoryItem* item) const; bool checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const; bool checkAgainstCreator(const class LLFolderViewModelItemInventory* listener) const; + bool checkAgainstSearchVisibility(const class LLFolderViewModelItemInventory* listener) const; bool checkAgainstClipboard(const LLUUID& object_id) const; FilterOps mFilterOps; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 7a0ea8b668..f2e06d19f3 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -774,40 +774,45 @@ void show_item_profile(const LLUUID& item_uuid) void show_item_original(const LLUUID& item_uuid) { - LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory"); - if (!floater_inventory) - { - LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL; - return; - } - - //sidetray inventory panel - LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - - bool do_reset_inventory_filter = !floater_inventory->isInVisibleChain(); + LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory"); + if (!floater_inventory) + { + LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL; + return; + } + LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + if (sidepanel_inventory) + { + LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); + if (main_inventory) + { + main_inventory->resetFilters(); + } + reset_inventory_filter(); - LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(); - if (!active_panel) - { - //this may happen when there is no floatera and other panel is active in inventory tab + if (!LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("inventory")->isInVisibleChain()) + { + LLFloaterReg::toggleInstanceOrBringToFront("inventory"); + } - if (sidepanel_inventory) - { - sidepanel_inventory->showInventoryPanel(); - } - } - - active_panel = LLInventoryPanel::getActiveInventoryPanel(); - if (!active_panel) - { - return; - } - active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES); - - if(do_reset_inventory_filter) - { - reset_inventory_filter(); - } + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); + if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id)) + { + if (sidepanel_inventory->getInboxPanel()) + { + sidepanel_inventory->openInbox(); + sidepanel_inventory->getInboxPanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES); + } + } + else + { + sidepanel_inventory->selectAllItemsPanel(); + if (sidepanel_inventory->getActivePanel()) + { + sidepanel_inventory->getActivePanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES); + } + } + } } @@ -1842,6 +1847,26 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ return result && !has_bad_items; } +void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id) +{ + LLInventoryItem* inv_item = gInventory.getItem(item_id); + if (inv_item) + { + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); + + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item); + new_item->setParent(new_parent_id); + new_item->updateParentOnServer(FALSE); + gInventory.updateItem(new_item); + gInventory.notifyObservers(); + } +} + ///---------------------------------------------------------------------------- /// LLInventoryCollectFunctor implementations ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 04eb962372..37c3c47336 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -92,6 +92,8 @@ S32 depth_nesting_in_marketplace(LLUUID cur_uuid); LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth); S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false); +void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id); + /** Miscellaneous global functions ** ** *******************************************************************************/ diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 74d9e895c2..3608f9e23f 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -158,7 +158,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mViewsInitialized(VIEWS_UNINITIALIZED), mInvFVBridgeBuilder(NULL), mInventoryViewModel(p.name), - mGroupedItemBridge(new LLFolderViewGroupedItemBridge) + mGroupedItemBridge(new LLFolderViewGroupedItemBridge), + mFocusSelection(false) { mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; @@ -1240,6 +1241,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std:: void LLInventoryPanel::clearSelection() { mSelectThisID.setNull(); + mFocusSelection = false; } LLInventoryPanel::selected_items_t LLInventoryPanel::getSelectedItems() const @@ -1714,15 +1716,17 @@ LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id) void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL take_keyboard_focus ) { LLFolderViewItem* itemp = getItemByID(obj_id); - if(itemp && itemp->getViewModelItem()) + if(itemp && itemp->getViewModelItem() && itemp->passedFilter()) { itemp->arrangeAndSet(TRUE, take_keyboard_focus); mSelectThisID.setNull(); + mFocusSelection = false; return; } else { // save the desired item to be selected later (if/when ready) + mFocusSelection = take_keyboard_focus; mSelectThisID = obj_id; } } @@ -1731,7 +1735,7 @@ void LLInventoryPanel::updateSelection() { if (mSelectThisID.notNull()) { - setSelectionByID(mSelectThisID, false); + setSelectionByID(mSelectThisID, mFocusSelection); } } diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index ad6010f09c..a019fc2231 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -269,6 +269,7 @@ protected: LLInventoryModel* mInventory; LLInventoryObserver* mInventoryObserver; LLInvPanelComplObserver* mCompletionObserver; + bool mFocusSelection; bool mAcceptsDragAndDrop; bool mAllowMultiSelect; bool mAllowDrag; @@ -366,27 +367,6 @@ private: EViewsInitializationState mViewsInitialized; // Whether views have been generated }; - -class LLInventoryFavoriteItemsPanel : public LLInventoryPanel -{ -public: - struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params> - {}; - - void initFromParams(const Params& p); - bool isSelectionRemovable() { return false; } - void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb); - -protected: - LLInventoryFavoriteItemsPanel(const Params& params); - ~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); } - void updateFavoritesRootFolder(); - - boost::signals2::connection mFolderChangedSignal; - boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback; - friend class LLUICtrlFactory; -}; - /************************************************************************/ /* Asset Pre-Filtered Inventory Panel related class */ /* Exchanges filter's flexibility for speed of generation and */ diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp index c243f8b4f0..a17dc674ac 100644 --- a/indra/newview/lllandmarkactions.cpp +++ b/indra/newview/lllandmarkactions.cpp @@ -228,23 +228,6 @@ LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos() return findLandmarkForGlobalPos(gAgent.getPositionGlobal()); } -bool LLLandmarkActions::canCreateLandmarkHere() -{ - LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if(!agent_parcel) - { - LL_WARNS() << "No agent region" << LL_ENDL; - return false; - } - if (agent_parcel->getAllowLandmark() - || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) - { - return true; - } - - return false; -} - void LLLandmarkActions::createLandmarkHere( const std::string& name, const std::string& desc, @@ -261,11 +244,6 @@ void LLLandmarkActions::createLandmarkHere( LL_WARNS() << "No agent parcel" << LL_ENDL; return; } - if (!canCreateLandmarkHere()) - { - LLNotificationsUtil::add("CannotCreateLandmarkNotOwner"); - return; - } create_inventory_item(gAgent.getID(), gAgent.getSessionID(), folder_id, LLTransactionID::tnull, diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h index 870d92811e..ae7b072fcb 100644 --- a/indra/newview/lllandmarkactions.h +++ b/indra/newview/lllandmarkactions.h @@ -72,12 +72,6 @@ public: */ static LLViewerInventoryItem* findLandmarkForAgentPos(); - - /** - * @brief Checks whether agent has rights to create landmark for current parcel. - */ - static bool canCreateLandmarkHere(); - /** * @brief Creates landmark for current parcel. */ diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 83195e9e3f..d6f3068610 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -44,6 +44,7 @@ // newview includes #include "llagent.h" +#include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llinventoryobserver.h" #include "lllandmarkactions.h" @@ -653,7 +654,7 @@ void LLLocationInputCtrl::onAddLandmarkButtonClicked() } else { - LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); + LLFloaterReg::showInstance("add_landmark"); } } @@ -1126,7 +1127,7 @@ void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata) if(!landmark) { - LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); + LLFloaterReg::showInstance("add_landmark"); } else { diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 663a6071f7..4a8ef53a8b 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -726,7 +726,20 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id) msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_MuteData); msg->addU32Fast(_PREHASH_MuteCRC, crc.getCRC()); - gAgent.sendReliableMessage(); + + if (gDisconnected) + { + LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL; + return; + } + if (!gAgent.getRegion()) + { + LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL; + return; + } + // Double amount of retries due to this request happening during busy stage + // Ideally this should be turned into a capability + gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL); } //----------------------------------------------------------------------------- diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 179c64b5c5..19dbbeb60e 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -58,6 +58,7 @@ #include "llweb.h" #include "llhints.h" +#include "llfloatersidepanelcontainer.h" #include "llinventorymodel.h" #include "lllandmarkactions.h" @@ -290,6 +291,7 @@ BOOL LLNavigationBar::postBuild() mBtnBack = getChild<LLPullButton>("back_btn"); mBtnForward = getChild<LLPullButton>("forward_btn"); mBtnHome = getChild<LLButton>("home_btn"); + mBtnLandmarks = getChild<LLButton>("landmarks_btn"); mCmbLocation= getChild<LLLocationInputCtrl>("location_combo"); @@ -305,6 +307,8 @@ BOOL LLNavigationBar::postBuild() mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this)); + mBtnLandmarks->setClickedCallback(boost::bind(&LLNavigationBar::onLandmarksButtonClicked, this)); + mCmbLocation->setCommitCallback(boost::bind(&LLNavigationBar::onLocationSelection, this)); mTeleportFinishConnection = LLViewerParcelMgr::getInstance()-> @@ -401,6 +405,12 @@ void LLNavigationBar::onHomeButtonClicked() gAgent.teleportHome(); } +void LLNavigationBar::onLandmarksButtonClicked() +{ + LLFloaterReg::toggleInstanceOrBringToFront("places"); + LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "open_landmark_tab")); +} + void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata) { int idx = userdata.asInteger(); diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index a44c6dd699..646911a62c 100755 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -119,6 +119,7 @@ private: void onNavigationButtonHeldUp(LLButton* nav_button); void onForwardButtonClicked(); void onHomeButtonClicked(); + void onLandmarksButtonClicked(); void onLocationSelection(); void onLocationPrearrange(const LLSD& data); void onTeleportFinished(const LLVector3d& global_agent_pos); @@ -144,6 +145,7 @@ private: LLPullButton* mBtnBack; LLPullButton* mBtnForward; LLButton* mBtnHome; + LLButton* mBtnLandmarks; LLLocationInputCtrl* mCmbLocation; LLRect mDefaultNbRect; LLRect mDefaultFpRect; diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp index 2e26b69144..a169712bd8 100644 --- a/indra/newview/llpaneleditsky.cpp +++ b/indra/newview/llpaneleditsky.cpp @@ -69,11 +69,15 @@ namespace const std::string FIELD_SKY_GLOW_SIZE("glow_size"); const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness"); const std::string FIELD_SKY_SUN_ROTATION("sun_rotation"); + const std::string FIELD_SKY_SUN_AZIMUTH("sun_azimuth"); + const std::string FIELD_SKY_SUN_ELEVATION("sun_elevation"); const std::string FIELD_SKY_SUN_IMAGE("sun_image"); const std::string FIELD_SKY_SUN_SCALE("sun_scale"); const std::string FIELD_SKY_SUN_BEACON("sunbeacon"); const std::string FIELD_SKY_MOON_BEACON("moonbeacon"); const std::string FIELD_SKY_MOON_ROTATION("moon_rotation"); + const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth"); + const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation"); const std::string FIELD_SKY_MOON_IMAGE("moon_image"); const std::string FIELD_SKY_MOON_SCALE("moon_scale"); const std::string FIELD_SKY_MOON_BRIGHTNESS("moon_brightness"); @@ -473,12 +477,16 @@ BOOL LLPanelSettingsSkySunMoonTab::postBuild() getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); }); getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); }); getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); }); getChild<LLUICtrl>(FIELD_SKY_SUN_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunImageChanged(); }); getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); }); getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetBlankSunTextureId()); getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetBlankSunTextureId()); getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setAllowNoTexture(TRUE); getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); }); getChild<LLUICtrl>(FIELD_SKY_MOON_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonImageChanged(); }); getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetDefaultMoonTextureId()); getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetDefaultMoonTextureId()); @@ -537,13 +545,29 @@ void LLPanelSettingsSkySunMoonTab::refresh() getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B); getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mSkySettings->getStarBrightness()); - getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mSkySettings->getSunRotation()); getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setValue(mSkySettings->getSunTextureId()); getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mSkySettings->getSunScale()); - getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mSkySettings->getMoonRotation()); getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setValue(mSkySettings->getMoonTextureId()); getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setValue(mSkySettings->getMoonScale()); getChild<LLUICtrl>(FIELD_SKY_MOON_BRIGHTNESS)->setValue(mSkySettings->getMoonBrightness()); + + // Sun rotation values + F32 azimuth, elevation; + LLQuaternion quat = mSkySettings->getSunRotation(); + LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + + getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat); + getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth); + getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation); + + // Moon rotation values + quat = mSkySettings->getMoonRotation(); + LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + + getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat); + getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth); + getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation); + } //------------------------------------------------------------------------- @@ -583,10 +607,47 @@ void LLPanelSettingsSkySunMoonTab::onStarBrightnessChanged() void LLPanelSettingsSkySunMoonTab::onSunRotationChanged() { - if (!mSkySettings) return; - mSkySettings->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation()); - mSkySettings->update(); - setIsDirty(); + LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation(); + + F32 azimuth, elevation; + LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth); + getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation); + if (mSkySettings) + { + mSkySettings->setSunRotation(quat); + mSkySettings->update(); + setIsDirty(); + } +} + +void LLPanelSettingsSkySunMoonTab::onSunAzimElevChanged() +{ + F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal(); + F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal(); + LLQuaternion quat; + + azimuth *= DEG_TO_RAD; + elevation *= DEG_TO_RAD; + + if (is_approx_zero(elevation)) + { + elevation = F_APPROXIMATELY_ZERO; + } + + quat.setAngleAxis(-elevation, 0, 1, 0); + LLQuaternion az_quat; + az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1); + quat *= az_quat; + + getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat); + + if (mSkySettings) + { + mSkySettings->setSunRotation(quat); + mSkySettings->update(); + setIsDirty(); + } } void LLPanelSettingsSkySunMoonTab::onSunScaleChanged() @@ -607,10 +668,48 @@ void LLPanelSettingsSkySunMoonTab::onSunImageChanged() void LLPanelSettingsSkySunMoonTab::onMoonRotationChanged() { - if (!mSkySettings) return; - mSkySettings->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation()); - mSkySettings->update(); - setIsDirty(); + LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation(); + + F32 azimuth, elevation; + LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth); + getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation); + + if (mSkySettings) + { + mSkySettings->setMoonRotation(quat); + mSkySettings->update(); + setIsDirty(); + } +} + +void LLPanelSettingsSkySunMoonTab::onMoonAzimElevChanged() +{ + F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal(); + F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal(); + LLQuaternion quat; + + azimuth *= DEG_TO_RAD; + elevation *= DEG_TO_RAD; + + if (is_approx_zero(elevation)) + { + elevation = F_APPROXIMATELY_ZERO; + } + + quat.setAngleAxis(-elevation, 0, 1, 0); + LLQuaternion az_quat; + az_quat.setAngleAxis(F_TWO_PI- azimuth, 0, 0, 1); + quat *= az_quat; + + getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat); + + if (mSkySettings) + { + mSkySettings->setMoonRotation(quat); + mSkySettings->update(); + setIsDirty(); + } } void LLPanelSettingsSkySunMoonTab::onMoonImageChanged() diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h index 801fb8b9b2..cb63d40b0c 100644 --- a/indra/newview/llpaneleditsky.h +++ b/indra/newview/llpaneleditsky.h @@ -124,9 +124,11 @@ private: void onGlowChanged(); void onStarBrightnessChanged(); void onSunRotationChanged(); + void onSunAzimElevChanged(); void onSunScaleChanged(); void onSunImageChanged(); void onMoonRotationChanged(); + void onMoonAzimElevChanged(); void onMoonScaleChanged(); void onMoonBrightnessChanged(); void onMoonImageChanged(); diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index 6751c25fb9..880323ce16 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -52,7 +52,6 @@ typedef std::pair<LLUUID, std::string> folder_pair_t; static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right); -static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats); static LLPanelInjector<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info"); @@ -107,6 +106,18 @@ void LLPanelLandmarkInfo::resetLocation() // virtual void LLPanelLandmarkInfo::setInfoType(EInfoType type) { + LLUUID dest_folder; + setInfoType(type, dest_folder); +} + +// Sets CREATE_LANDMARK infotype and creates landmark at desired folder +void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& fodler_id) +{ + setInfoType(CREATE_LANDMARK, fodler_id); +} + +void LLPanelLandmarkInfo::setInfoType(EInfoType type, const LLUUID &folder_id) +{ LLPanel* landmark_info_panel = getChild<LLPanel>("landmark_info_panel"); bool is_info_type_create_landmark = type == CREATE_LANDMARK; @@ -183,7 +194,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type) // remote parcel request to complete. if (!LLLandmarkActions::landmarkAlreadyExists()) { - createLandmark(LLUUID()); + createLandmark(folder_id); } } break; @@ -504,7 +515,7 @@ static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) return left.second < right.second; } -static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) +void LLPanelLandmarkInfo::collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) { LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); @@ -517,16 +528,20 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) items, LLInventoryModel::EXCLUDE_TRASH, is_category); +} - // Add the "My Favorites" category. - LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id); - if (!favorites_cat) - { - LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL; - } - else - { - cats.push_back(favorites_cat); - } +/* virtual */ void LLUpdateLandmarkParent::fire(const LLUUID& inv_item_id) +{ + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); + + mItem->setParent(mNewParentId); + mItem->updateParentOnServer(FALSE); + + gInventory.updateItem(mItem); + gInventory.notifyObservers(); } diff --git a/indra/newview/llpanellandmarkinfo.h b/indra/newview/llpanellandmarkinfo.h index 9712736182..f727f286b5 100644 --- a/indra/newview/llpanellandmarkinfo.h +++ b/indra/newview/llpanellandmarkinfo.h @@ -28,6 +28,7 @@ #define LL_LLPANELLANDMARKINFO_H #include "llpanelplaceinfo.h" +#include "llinventorymodel.h" class LLComboBox; class LLLineEditor; @@ -43,8 +44,12 @@ public: /*virtual*/ void resetLocation(); + // If landmark doesn't exists, will create it at default folder /*virtual*/ void setInfoType(EInfoType type); + // Sets CREATE_LANDMARK infotype and creates landmark at desired folder + void setInfoAndCreateLandmark(const LLUUID& fodler_id); + /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); // Displays landmark owner, creator and creation date info. @@ -59,13 +64,19 @@ public: // Select current landmark folder in combobox. BOOL setLandmarkFolder(const LLUUID& id); - // Create a landmark for the current location - // in a folder specified by folder_id. - void createLandmark(const LLUUID& folder_id); - + typedef std::vector<LLPointer<LLViewerInventoryCategory> > cat_array_t; static std::string getFullFolderName(const LLViewerInventoryCategory* cat); + static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats); private: + // Create a landmark for the current location + // in a folder specified by folder_id. + // Expects title and description to be initialized + void createLandmark(const LLUUID& folder_id); + + // If landmark doesn't exists, will create it at specified folder + void setInfoType(EInfoType type, const LLUUID &folder_id); + void populateFoldersList(); LLTextBox* mOwner; @@ -77,4 +88,17 @@ private: LLComboBox* mFolderCombo; }; +class LLUpdateLandmarkParent : public LLInventoryCallback +{ +public: + LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) : + mItem(item), + mNewParentId(new_parent) + {}; + /* virtual */ void fire(const LLUUID& inv_item_id); + +private: + LLPointer<LLViewerInventoryItem> mItem; + LLUUID mNewParentId; +}; #endif // LL_LLPANELLANDMARKINFO_H diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index ccd8497484..e698a61fef 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -36,12 +36,11 @@ #include "llregionhandle.h" #include "llaccordionctrl.h" -#include "llaccordionctrltab.h" #include "llagent.h" #include "llagentpicksinfo.h" #include "llagentui.h" +#include "llavataractions.h" #include "llcallbacklist.h" -#include "lldndbutton.h" #include "llfloatersidepanelcontainer.h" #include "llfloaterworldmap.h" #include "llfolderviewitem.h" @@ -60,15 +59,8 @@ // Not yet implemented; need to remove buildPanel() from constructor when we switch //static LLRegisterPanelClassWrapper<LLLandmarksPanel> t_landmarks("panel_landmarks"); -static const std::string OPTIONS_BUTTON_NAME = "options_gear_btn"; -static const std::string ADD_BUTTON_NAME = "add_btn"; -static const std::string ADD_FOLDER_BUTTON_NAME = "add_folder_btn"; -static const std::string TRASH_BUTTON_NAME = "trash_btn"; - - // helper functions static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string); -static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list); static void collapse_all_folders(LLFolderView* root_folder); static void expand_all_folders(LLFolderView* root_folder); static bool has_expanded_folders(LLFolderView* root_folder); @@ -149,69 +141,37 @@ void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder) } } -/** - * Bridge to support knowing when the inventory has changed to update Landmarks tab - * ShowFolderState filter setting to show all folders when the filter string is empty and - * empty folder message when Landmarks inventory category has no children. - * Ensures that "Landmarks" folder in the Library is open on strart up. - */ -class LLLandmarksPanelObserver : public LLInventoryObserver -{ -public: - LLLandmarksPanelObserver(LLLandmarksPanel* lp) - : mLP(lp), - mIsLibraryLandmarksOpen(false) - {} - virtual ~LLLandmarksPanelObserver() {} - /*virtual*/ void changed(U32 mask); - -private: - LLLandmarksPanel* mLP; - bool mIsLibraryLandmarksOpen; -}; - -void LLLandmarksPanelObserver::changed(U32 mask) +LLLandmarksPanel::LLLandmarksPanel() + : LLPanelPlacesTab() + , mLandmarksInventoryPanel(NULL) + , mCurrentSelectedList(NULL) + , mGearFolderMenu(NULL) + , mGearLandmarkMenu(NULL) + , mSortingMenu(NULL) + , mAddMenu(NULL) + , isLandmarksPanel(true) { - mLP->updateShowFolderState(); - - LLPlacesInventoryPanel* library = mLP->getLibraryInventoryPanel(); - if (!mIsLibraryLandmarksOpen && library) - { - // Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827. - const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); - if (landmarks_cat.notNull()) - { - LLOpenFolderByID opener(landmarks_cat); - library->getRootFolder()->applyFunctorRecursively(opener); - mIsLibraryLandmarksOpen = opener.isFolderOpen(); - } - } + buildFromFile("panel_landmarks.xml"); } -LLLandmarksPanel::LLLandmarksPanel() +LLLandmarksPanel::LLLandmarksPanel(bool is_landmark_panel) : LLPanelPlacesTab() - , mFavoritesInventoryPanel(NULL) , mLandmarksInventoryPanel(NULL) - , mMyInventoryPanel(NULL) - , mLibraryInventoryPanel(NULL) , mCurrentSelectedList(NULL) - , mListCommands(NULL) - , mGearButton(NULL) , mGearFolderMenu(NULL) , mGearLandmarkMenu(NULL) + , mSortingMenu(NULL) + , mAddMenu(NULL) + , isLandmarksPanel(is_landmark_panel) { - mInventoryObserver = new LLLandmarksPanelObserver(this); - gInventory.addObserver(mInventoryObserver); - - buildFromFile( "panel_landmarks.xml"); + if (is_landmark_panel) + { + buildFromFile("panel_landmarks.xml"); + } } LLLandmarksPanel::~LLLandmarksPanel() { - if (gInventory.containsObserver(mInventoryObserver)) - { - gInventory.removeObserver(mInventoryObserver); - } } BOOL LLLandmarksPanel::postBuild() @@ -221,17 +181,7 @@ BOOL LLLandmarksPanel::postBuild() // mast be called before any other initXXX methods to init Gear menu initListCommandsHandlers(); - - initFavoritesInventoryPanel(); initLandmarksInventoryPanel(); - initMyInventoryPanel(); - initLibraryInventoryPanel(); - - LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion"); - if (accordion) - { - accordion->setSkipScrollToChild(true); - } return TRUE; } @@ -239,30 +189,10 @@ BOOL LLLandmarksPanel::postBuild() // virtual void LLLandmarksPanel::onSearchEdit(const std::string& string) { - // give FolderView a chance to be refreshed. So, made all accordions visible - for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) - { - LLAccordionCtrlTab* tab = *iter; - tab->setVisible(TRUE); - - // expand accordion to see matched items in each one. See EXT-2014. - if (string != "") - { - tab->changeOpenClose(false); - } - - LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView()); - if (NULL == inventory_list) continue; - - filter_list(inventory_list, string); - } + filter_list(mCurrentSelectedList, string); if (sFilterSubString != string) sFilterSubString = string; - - // show all folders in Landmarks Accordion for empty filter - // only if Landmarks inventory folder is not empty - updateShowFolderState(); } // virtual @@ -274,11 +204,6 @@ void LLLandmarksPanel::onShowOnMap() return; } - // Disable the "Map" button because loading landmark can take some time. - // During this time the button is useless. It will be enabled on callback finish - // or upon switching to other item. - mShowOnMapBtn->setEnabled(FALSE); - doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doShowOnMap, this, _1)); } @@ -303,6 +228,12 @@ void LLLandmarksPanel::onTeleport() } } +/*virtual*/ +void LLLandmarksPanel::onRemoveSelected() +{ + onClipboardAction("delete"); +} + // virtual bool LLLandmarksPanel::isSingleItemSelected() { @@ -322,86 +253,55 @@ bool LLLandmarksPanel::isSingleItemSelected() } // virtual -void LLLandmarksPanel::updateVerbs() -{ - if (!isTabVisible()) - return; - - bool landmark_selected = isLandmarkSelected(); - mTeleportBtn->setEnabled(landmark_selected && isActionEnabled("teleport")); - mShowProfile->setEnabled(landmark_selected && isActionEnabled("more_info")); - mShowOnMapBtn->setEnabled(landmark_selected && isActionEnabled("show_on_map")); - - // TODO: mantipov: Uncomment when mShareBtn is supported - // Share button should be enabled when neither a folder nor a landmark is selected - //mShareBtn->setEnabled(NULL != current_item); - - updateListCommands(); +LLToggleableMenu* LLLandmarksPanel::getSelectionMenu() +{ + LLToggleableMenu* menu = mGearFolderMenu; + + if (mCurrentSelectedList) + { + LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem(); + if (!listenerp) + return menu; + + if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + menu = mGearLandmarkMenu; + } + } + return menu; } -void LLLandmarksPanel::onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action) +// virtual +LLToggleableMenu* LLLandmarksPanel::getSortingMenu() { - if (user_action && (items.size() > 0)) - { - deselectOtherThan(inventory_list); - mCurrentSelectedList = inventory_list; - } - updateVerbs(); + return mSortingMenu; } -void LLLandmarksPanel::onSelectorButtonClicked() +// virtual +LLToggleableMenu* LLLandmarksPanel::getCreateMenu() { - // TODO: mantipov: update getting of selected item - // TODO: bind to "i" button - LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem(); - if (!cur_item) return; - - LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem()); - if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) - { - LLSD key; - key["type"] = "landmark"; - key["id"] = listenerp->getUUID(); - - LLFloaterSidePanelContainer::showPanel("places", key); - } + return mAddMenu; } -void LLLandmarksPanel::updateShowFolderState() +void LLLandmarksPanel::updateVerbs() { - bool show_all_folders = mLandmarksInventoryPanel->getFilterSubString().empty(); - if (show_all_folders) + if (sRemoveBtn) { - show_all_folders = category_has_descendents(mLandmarksInventoryPanel); + sRemoveBtn->setEnabled(isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected())); } - - mLandmarksInventoryPanel->setShowFolderState(show_all_folders ? - LLInventoryFilter::SHOW_ALL_FOLDERS : - LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS - ); } void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus) { - if (selectItemInAccordionTab(mFavoritesInventoryPanel, "tab_favorites", obj_id, take_keyboard_focus)) - { + if (!mCurrentSelectedList) return; - } - if (selectItemInAccordionTab(mLandmarksInventoryPanel, "tab_landmarks", obj_id, take_keyboard_focus)) - { - return; - } - - if (selectItemInAccordionTab(mMyInventoryPanel, "tab_inventory", obj_id, take_keyboard_focus)) - { - return; - } - - if (selectItemInAccordionTab(mLibraryInventoryPanel, "tab_library", obj_id, take_keyboard_focus)) - { + LLFolderView* root = mCurrentSelectedList->getRootFolder(); + LLFolderViewItem* item = mCurrentSelectedList->getItemByID(obj_id); + if (!item) return; - } + root->setSelection(item, FALSE, take_keyboard_focus); + root->scrollToShowSelection(); } ////////////////////////////////////////////////////////////////////////// @@ -420,18 +320,6 @@ bool LLLandmarksPanel::isFolderSelected() const return current_item && (current_item->getInventoryType() == LLInventoryType::IT_CATEGORY); } -bool LLLandmarksPanel::isReceivedFolderSelected() const -{ - // Received Folder can be only in Landmarks accordion - if (mCurrentSelectedList != mLandmarksInventoryPanel) return false; - - // *TODO: it should be filled with logic when EXT-976 is done. - - LL_WARNS() << "Not implemented yet until EXT-976 is done." << LL_ENDL; - - return false; -} - void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb) { LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); @@ -461,36 +349,6 @@ LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem() } -LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list, - const std::string& tab_name, - const LLUUID& obj_id, - BOOL take_keyboard_focus) const -{ - if (!inventory_list) - return NULL; - - LLFolderView* root = inventory_list->getRootFolder(); - - LLFolderViewItem* item = inventory_list->getItemByID(obj_id); - if (!item) - return NULL; - - LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(tab_name); - if (!tab->isExpanded()) - { - tab->changeOpenClose(false); - } - - root->setSelection(item, FALSE, take_keyboard_focus); - - LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion"); - LLRect screen_rc; - localRectToScreen(item->getRect(), &screen_rc); - accordion->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue())); - - return item; -} - void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate) { if(!panel) return; @@ -506,19 +364,29 @@ void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate) } } +void LLLandmarksPanel::resetSelection() +{ +} + // virtual void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data) { //this function will be called after user will try to create a pick for selected landmark. // We have to make request to sever to get parcel_id and snaption_id. - if(isLandmarkSelected()) + if(mCreatePickItemId.notNull()) { - LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); - if (!cur_item) return; - LLUUID id = cur_item->getUUID(); - LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id); - doActionOnCurSelectedLandmark(boost::bind( - &LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data)); + LLInventoryItem* inv_item = gInventory.getItem(mCreatePickItemId); + + if (inv_item && inv_item->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + // we are processing response for doCreatePick, landmark should be already loaded + LLLandmark* landmark = LLLandmarkActions::getLandmark(inv_item->getUUID()); + if (landmark) + { + doProcessParcelInfo(landmark, inv_item, parcel_data); + } + } + mCreatePickItemId.setNull(); } } @@ -543,16 +411,6 @@ void LLLandmarksPanel::setErrorStatus(S32 status, const std::string& reason) // PRIVATE METHODS ////////////////////////////////////////////////////////////////////////// -void LLLandmarksPanel::initFavoritesInventoryPanel() -{ - mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list"); - - initLandmarksPanel(mFavoritesInventoryPanel); - mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems"); - - initAccordion("tab_favorites", mFavoritesInventoryPanel, true); -} - void LLLandmarksPanel::initLandmarksInventoryPanel() { mLandmarksInventoryPanel = getChild<LLPlacesInventoryPanel>("landmarks_list"); @@ -564,40 +422,14 @@ void LLLandmarksPanel::initLandmarksInventoryPanel() // subscribe to have auto-rename functionality while creating New Folder mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2)); - mMyLandmarksAccordionTab = initAccordion("tab_landmarks", mLandmarksInventoryPanel, true); -} - -void LLLandmarksPanel::initMyInventoryPanel() -{ - mMyInventoryPanel= getChild<LLPlacesInventoryPanel>("my_inventory_list"); - - initLandmarksPanel(mMyInventoryPanel); - - initAccordion("tab_inventory", mMyInventoryPanel, false); -} - -void LLLandmarksPanel::initLibraryInventoryPanel() -{ - mLibraryInventoryPanel = getChild<LLPlacesInventoryPanel>("library_list"); - - initLandmarksPanel(mLibraryInventoryPanel); - - // We want to fetch only "Landmarks" category from the library. - const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); - if (landmarks_cat.notNull()) - { - LLInventoryModelBackgroundFetch::instance().start(landmarks_cat); - } - - // Expanding "Library" tab for new users who have no landmarks in "My Inventory". - initAccordion("tab_library", mLibraryInventoryPanel, true); + mCurrentSelectedList = mLandmarksInventoryPanel; } void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list) { inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems"); inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK); - inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); + inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::updateVerbs, this)); inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); @@ -615,86 +447,10 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list inventory_list->saveFolderState(); } -LLAccordionCtrlTab* LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab) -{ - LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name); - - mAccordionTabs.push_back(accordion_tab); - accordion_tab->setDropDownStateChangedCallback( - boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list)); - accordion_tab->setDisplayChildren(expand_tab); - return accordion_tab; -} - -void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list) -{ - bool expanded = param.asBoolean(); - - if(!expanded && (mCurrentSelectedList == inventory_list)) - { - inventory_list->getRootFolder()->clearSelection(); - - mCurrentSelectedList = NULL; - updateVerbs(); - } - - // Start background fetch, mostly for My Inventory and Library - if (expanded) - { - const LLUUID &cat_id = inventory_list->getRootFolderID(); - // Just because the category itself has been fetched, doesn't mean its child folders have. - /* - if (!gInventory.isCategoryComplete(cat_id)) - */ - { - LLInventoryModelBackgroundFetch::instance().start(cat_id); - } - - // Apply filter substring because it might have been changed - // while accordion was closed. See EXT-3714. - filter_list(inventory_list, sFilterSubString); - } -} - -void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory_list) -{ - if (inventory_list != mFavoritesInventoryPanel) - { - mFavoritesInventoryPanel->clearSelection(); - } - - if (inventory_list != mLandmarksInventoryPanel) - { - mLandmarksInventoryPanel->clearSelection(); - } - if (inventory_list != mMyInventoryPanel) - { - mMyInventoryPanel->clearSelection(); - } - if (inventory_list != mLibraryInventoryPanel) - { - mLibraryInventoryPanel->clearSelection(); - } -} // List Commands Handlers void LLLandmarksPanel::initListCommandsHandlers() { - mListCommands = getChild<LLPanel>("bottom_panel"); - - mGearButton = getChild<LLMenuButton>(OPTIONS_BUTTON_NAME); - mGearButton->setMouseDownCallback(boost::bind(&LLLandmarksPanel::onActionsButtonClick, this)); - - mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this)); - - LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>(TRASH_BUTTON_NAME); - trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this - , _4 // BOOL drop - , _5 // EDragAndDropType cargo_type - , _6 // void* cargo_data - , _7 // EAcceptance* accept - )); - mCommitCallbackRegistrar.add("Places.LandmarksGear.Add.Action", boost::bind(&LLLandmarksPanel::onAddAction, this, _2)); mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onClipboardAction, this, _2)); mCommitCallbackRegistrar.add("Places.LandmarksGear.Custom.Action", boost::bind(&LLLandmarksPanel::onCustomAction, this, _2)); @@ -703,23 +459,16 @@ void LLLandmarksPanel::initListCommandsHandlers() mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2)); mGearLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mSortingMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_sorting.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mAddMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGearLandmarkMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2)); mGearFolderMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2)); - mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::showActionMenu, this, mMenuAdd, ADD_BUTTON_NAME)); -} - - -void LLLandmarksPanel::updateListCommands() -{ - bool add_folder_enabled = isActionEnabled("category"); - bool trash_enabled = isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected()); - - // keep Options & Add Landmark buttons always enabled - mListCommands->getChildView(ADD_FOLDER_BUTTON_NAME)->setEnabled(add_folder_enabled); - mListCommands->getChildView(TRASH_BUTTON_NAME)->setEnabled(trash_enabled); + // show menus even if all items are disabled + mGearLandmarkMenu->setAlwaysShowMenu(TRUE); + mGearFolderMenu->setAlwaysShowMenu(TRUE); + mAddMenu->setAlwaysShowMenu(TRUE); } void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu) @@ -727,43 +476,6 @@ void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu) onMenuVisibilityChange(menu, LLSD().with("visibility", true)); } -void LLLandmarksPanel::onActionsButtonClick() -{ - LLToggleableMenu* menu = mGearFolderMenu; - - if(mCurrentSelectedList) - { - LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem(); - if(!listenerp) - return; - - if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) - { - menu = mGearLandmarkMenu; - } - } - - mGearButton->setMenu(menu); -} - -void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) -{ - if (menu) - { - menu->buildDrawLabels(); - menu->updateParent(LLMenuGL::sMenuContainer); - menu->arrangeAndClear(); - - LLView* spawning_view = getChild<LLView>(spawning_view_name); - - S32 menu_x, menu_y; - //show menu in co-ordinates of panel - spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this); - menu_y += menu->getRect().getHeight(); - LLMenuGL::showPopup(this, menu, menu_x, menu_y); - } -} - void LLLandmarksPanel::onTrashButtonClick() const { onClipboardAction("delete"); @@ -775,7 +487,8 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const LLFolderViewItem* item = getCurSelectedItem(); std::string command_name = userdata.asString(); - if("add_landmark" == command_name) + if("add_landmark" == command_name + || "add_landmark_root" == command_name) { LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos(); if(landmark) @@ -784,7 +497,20 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const } else { - LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); + LLSD args; + args["type"] = "create_landmark"; + if ("add_landmark" == command_name + && view_model->getInventoryType() == LLInventoryType::IT_CATEGORY) + { + args["dest_folder"] = view_model->getUUID(); + } + if ("add_landmark_root" == command_name + && mCurrentSelectedList == mLandmarksInventoryPanel) + { + args["dest_folder"] = mLandmarksInventoryPanel->getRootFolderID(); + } + // else will end up in favorites + LLFloaterReg::showInstance("add_landmark", args); } } else if ("category" == command_name) @@ -816,13 +542,14 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const //in case My Landmarks tab is completely empty (thus cannot be determined as being selected) menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"), gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK)); - - if (mMyLandmarksAccordionTab) - { - mMyLandmarksAccordionTab->changeOpenClose(false); - } } } + else if ("category_root" == command_name) + { + //in case My Landmarks tab is completely empty (thus cannot be determined as being selected) + menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"), + gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK)); + } } void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const @@ -856,27 +583,11 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) if ("expand_all" == command_name) { - expand_all_folders(mFavoritesInventoryPanel->getRootFolder()); - expand_all_folders(mLandmarksInventoryPanel->getRootFolder()); - expand_all_folders(mMyInventoryPanel->getRootFolder()); - expand_all_folders(mLibraryInventoryPanel->getRootFolder()); - - for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) - { - (*iter)->changeOpenClose(false); - } + expand_all_folders(mCurrentSelectedList->getRootFolder()); } else if ("collapse_all" == command_name) { - collapse_all_folders(mFavoritesInventoryPanel->getRootFolder()); - collapse_all_folders(mLandmarksInventoryPanel->getRootFolder()); - collapse_all_folders(mMyInventoryPanel->getRootFolder()); - collapse_all_folders(mLibraryInventoryPanel->getRootFolder()); - - for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) - { - (*iter)->changeOpenClose(true); - } + collapse_all_folders(mCurrentSelectedList->getRootFolder()); } else if ("sort_by_date" == command_name) { @@ -884,8 +595,6 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) sorting_order=!sorting_order; gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order); updateSortOrder(mLandmarksInventoryPanel, sorting_order); - updateSortOrder(mMyInventoryPanel, sorting_order); - updateSortOrder(mLibraryInventoryPanel, sorting_order); } else { @@ -917,51 +626,21 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const ? mCurrentSelectedList->getRootFolder() : NULL; + bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1; + if ("collapse_all" == command_name) { - bool disable_collapse_all = !has_expanded_folders(mFavoritesInventoryPanel->getRootFolder()) - && !has_expanded_folders(mLandmarksInventoryPanel->getRootFolder()) - && !has_expanded_folders(mMyInventoryPanel->getRootFolder()) - && !has_expanded_folders(mLibraryInventoryPanel->getRootFolder()); - if (disable_collapse_all) - { - for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) - { - if ((*iter)->isExpanded()) - { - disable_collapse_all = false; - break; - } - } - } - - return !disable_collapse_all; + return has_expanded_folders(mCurrentSelectedList->getRootFolder()); } else if ("expand_all" == command_name) { - bool disable_expand_all = !has_collapsed_folders(mFavoritesInventoryPanel->getRootFolder()) - && !has_collapsed_folders(mLandmarksInventoryPanel->getRootFolder()) - && !has_collapsed_folders(mMyInventoryPanel->getRootFolder()) - && !has_collapsed_folders(mLibraryInventoryPanel->getRootFolder()); - if (disable_expand_all) - { - for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) - { - if (!(*iter)->isExpanded()) - { - disable_expand_all = false; - break; - } - } - } - - return !disable_expand_all; + return has_collapsed_folders(mCurrentSelectedList->getRootFolder()); } else if ("sort_by_date" == command_name) { - // disable "sort_by_date" for Favorites accordion because + // disable "sort_by_date" for Favorites tab because // it has its own items order. EXT-1758 - if (mCurrentSelectedList == mFavoritesInventoryPanel) + if (!isLandmarksPanel) { return false; } @@ -978,6 +657,11 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList(); + if (selected_uuids.empty()) + { + return false; + } + // Allow to execute the command only if it can be applied to all selected items. for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) { @@ -998,7 +682,6 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const ) { // disable some commands for multi-selection. EXT-1757 - bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1; if (!is_single_selection) { return false; @@ -1017,9 +700,9 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const // Disable "Show on Map" if landmark loading is in progress. return !gLandmarkList.isAssetInLoadedCallbackMap(asset_uuid); - } - else if ("rename" == command_name) - { + } + else if ("rename" == command_name) + { LLFolderViewItem* selected_item = getCurSelectedItem(); if (!selected_item) return false; @@ -1028,16 +711,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const return true; } - else if("category" == command_name) - { - // we can add folder only in Landmarks Accordion - if (mCurrentSelectedList == mLandmarksInventoryPanel) - { - // ... but except Received folder - return !isReceivedFolderSelected(); - } - //"Add a folder" is enabled by default (case when My Landmarks is empty) - else return true; + if ("category_root" == command_name || "category" == command_name) + { + // we can add folder only in Landmarks tab + return isLandmarksPanel; } else if("create_pick" == command_name) { @@ -1051,6 +728,78 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const } return false; } + else if ("add_landmark" == command_name) + { + if (!is_single_selection) + { + return false; + } + + LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem(); + if (!view_model || view_model->getInventoryType() != LLInventoryType::IT_CATEGORY) + { + return false; + } + LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos(); + if (landmark) + { + //already exists + return false; + } + return true; + } + else if ("add_landmark_root" == command_name) + { + LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos(); + if (landmark) + { + //already exists + return false; + } + return true; + } + else if ("share" == command_name) + { + if (!mCurrentSelectedList) + { + return false; + } + if (!LLAvatarActions::canShareSelectedItems(mCurrentSelectedList)) + { + return false; + } + return true; + } + else if (command_name == "move_to_landmarks" || command_name == "move_to_favorites") + { + LLFolderViewModelItemInventory* cur_item_model = getCurSelectedViewModelItem(); + if (cur_item_model) + { + LLFolderType::EType folder_type = command_name == "move_to_landmarks" ? LLFolderType::FT_FAVORITE : LLFolderType::FT_LANDMARK; + if (!gInventory.isObjectDescendentOf(cur_item_model->getUUID(), gInventory.findCategoryUUIDForType(folder_type))) + { + return false; + } + + if (root_folder_view) + { + std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList(); + for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) + { + LLFolderViewItem* item = *iter; + if (!item) return false; + + cur_item_model = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem()); + if (!cur_item_model || cur_item_model->getInventoryType() != LLInventoryType::IT_LANDMARK) + { + return false; + } + } + return true; + } + } + return false; + } else { LL_WARNS() << "Unprocessed command has come: " << command_name << LL_ENDL; @@ -1076,12 +825,42 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata) } else if ("create_pick" == command_name) { - doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1)); + LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); + if (cur_item) + { + doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1, cur_item->getUUID())); + } } + else if ("share" == command_name && mCurrentSelectedList) + { + LLAvatarActions::shareWithAvatars(mCurrentSelectedList); + } else if ("restore" == command_name && mCurrentSelectedList) { mCurrentSelectedList->doToSelected(userdata); } + else if (command_name == "move_to_landmarks" || command_name == "move_to_favorites") + { + LLFolderView* root_folder_view = mCurrentSelectedList ? mCurrentSelectedList->getRootFolder() : NULL; + if (root_folder_view) + { + LLFolderType::EType folder_type = command_name == "move_to_landmarks" ? LLFolderType::FT_LANDMARK : LLFolderType::FT_FAVORITE; + std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList(); + for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) + { + LLFolderViewItem* item = *iter; + if (item) + { + LLFolderViewModelItemInventory* item_model = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem()); + if (item_model) + { + change_item_parent(item_model->getUUID(), gInventory.findCategoryUUIDForType(folder_type)); + } + } + } + } + + } } void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param) @@ -1148,29 +927,17 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold if (!item) return false; - // nothing can be modified in Library - if (mLibraryInventoryPanel == mCurrentSelectedList) return false; - bool can_be_modified = false; // landmarks can be modified in any other accordion... if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK) { can_be_modified = true; - - // we can modify landmarks anywhere except paste to My Inventory - if ("paste" == command_name) - { - can_be_modified = (mCurrentSelectedList != mMyInventoryPanel); - } } else { // ...folders only in the Landmarks accordion... - can_be_modified = mLandmarksInventoryPanel == mCurrentSelectedList; - - // ...except "Received" folder - can_be_modified &= !isReceivedFolderSelected(); + can_be_modified = isLandmarksPanel; } // then ask LLFolderView permissions @@ -1287,12 +1054,10 @@ void LLLandmarksPanel::doShowOnMap(LLLandmark* landmark) LLFloaterReg::showInstance("world_map", "center"); } - mShowOnMapBtn->setEnabled(TRUE); mGearLandmarkMenu->setItemEnabled("show_on_map", TRUE); } void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark, - LLFolderViewItem* cur_item, LLInventoryItem* inv_item, const LLParcelData& parcel_data) { @@ -1321,7 +1086,7 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark, LLPickData data; data.pos_global = landmark_global_pos; - data.name = cur_item->getName(); + data.name = inv_item->getName(); data.desc = inv_item->getDescription(); data.snapshot_id = parcel_data.snapshot_id; data.parcel_id = parcel_data.parcel_id; @@ -1341,11 +1106,13 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark, panel_pick, panel_places,params)); } -void LLLandmarksPanel::doCreatePick(LLLandmark* landmark) +void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id) { LLViewerRegion* region = gAgent.getRegion(); if (!region) return; + mCreatePickItemId = item_id; + LLGlobalVec pos_global; LLUUID region_id; landmark->getGlobalPos(pos_global); @@ -1398,27 +1165,12 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin inventory_list->setFilterSubString(string); } -static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list) -{ - LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID()); - if (category) - { - return category->getDescendentCount() > 0; - } - - return false; -} - static void collapse_all_folders(LLFolderView* root_folder) { if (!root_folder) return; root_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); - - // The top level folder is invisible, it must be open to - // display its sub-folders. - root_folder->openTopLevelFolders(); root_folder->arrangeAll(); } @@ -1485,4 +1237,31 @@ void toggle_restore_menu(LLMenuGL *menu, BOOL visible, BOOL enabled) } } } + +LLFavoritesPanel::LLFavoritesPanel() + : LLLandmarksPanel(false) +{ + buildFromFile("panel_favorites.xml"); +} + +BOOL LLFavoritesPanel::postBuild() +{ + if (!gInventory.isInventoryUsable()) + return FALSE; + + // mast be called before any other initXXX methods to init Gear menu + LLLandmarksPanel::initListCommandsHandlers(); + + initFavoritesInventoryPanel(); + + return TRUE; +} + +void LLFavoritesPanel::initFavoritesInventoryPanel() +{ + mCurrentSelectedList = getChild<LLPlacesInventoryPanel>("favorites_list"); + + LLLandmarksPanel::initLandmarksPanel(mCurrentSelectedList); + mCurrentSelectedList->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems"); +} // EOF diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index c11cbe05ae..d7408269b5 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -50,81 +50,69 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver { public: LLLandmarksPanel(); + LLLandmarksPanel(bool is_landmark_panel); virtual ~LLLandmarksPanel(); - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onSearchEdit(const std::string& string); - /*virtual*/ void onShowOnMap(); - /*virtual*/ void onShowProfile(); - /*virtual*/ void onTeleport(); - /*virtual*/ void updateVerbs(); - /*virtual*/ bool isSingleItemSelected(); + BOOL postBuild() override; + void onSearchEdit(const std::string& string) override; + void onShowOnMap() override; + void onShowProfile() override; + void onTeleport() override; + void onRemoveSelected() override; + void updateVerbs() override; + bool isSingleItemSelected() override; + + LLToggleableMenu* getSelectionMenu() override; + LLToggleableMenu* getSortingMenu() override; + LLToggleableMenu* getCreateMenu() override; + + /** + * Processes drag-n-drop of the Landmarks and folders into trash button. + */ + bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override; - void onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action); - void onSelectorButtonClicked(); void setCurrentSelectedList(LLPlacesInventoryPanel* inventory_list) { mCurrentSelectedList = inventory_list; } /** - * Update filter ShowFolderState setting to show empty folder message - * if Landmarks inventory folder is empty. - */ - void updateShowFolderState(); - - /** * Selects item with "obj_id" in one of accordion tabs. */ void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus); - LLPlacesInventoryPanel* getLibraryInventoryPanel() { return mLibraryInventoryPanel; } - void updateMenuVisibility(LLUICtrl* menu); + void doCreatePick(LLLandmark* landmark, const LLUUID &item_id ); + + void resetSelection(); + protected: /** * @return true - if current selected panel is not null and selected item is a landmark */ bool isLandmarkSelected() const; bool isFolderSelected() const; - bool isReceivedFolderSelected() const; void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb); LLFolderViewItem* getCurSelectedItem() const; LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const; - /** - * Selects item with "obj_id" in "inventory_list" and scrolls accordion - * scrollbar to show the item. - * Returns pointer to the item if it is found in "inventory_list", otherwise NULL. - */ - LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list, - const std::string& tab_name, - const LLUUID& obj_id, - BOOL take_keyboard_focus) const; - void updateSortOrder(LLInventoryPanel* panel, bool byDate); //LLRemoteParcelInfoObserver interface - /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); - /*virtual*/ void setParcelID(const LLUUID& parcel_id); - /*virtual*/ void setErrorStatus(S32 status, const std::string& reason); + void processParcelInfo(const LLParcelData& parcel_data) override; + void setParcelID(const LLUUID& parcel_id) override; + void setErrorStatus(S32 status, const std::string& reason) override; + + // List Commands Handlers + void initListCommandsHandlers(); + void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list); + + LLPlacesInventoryPanel* mCurrentSelectedList; private: - void initFavoritesInventoryPanel(); void initLandmarksInventoryPanel(); - void initMyInventoryPanel(); - void initLibraryInventoryPanel(); - void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list); - LLAccordionCtrlTab* initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab); - void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list); - void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list); - // List Commands Handlers - void initListCommandsHandlers(); - void updateListCommands(); - void onActionsButtonClick(); - void showActionMenu(LLMenuGL* menu, std::string spawning_view_name); void onTrashButtonClick() const; void onAddAction(const LLSD& command_name) const; void onClipboardAction(const LLSD& command_name) const; @@ -151,38 +139,33 @@ private: void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params); /** - * Processes drag-n-drop of the Landmarks and folders into trash button. - */ - bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept); - - /** * Landmark actions callbacks. Fire when a landmark is loaded from the list. */ void doShowOnMap(LLLandmark* landmark); void doProcessParcelInfo(LLLandmark* landmark, - LLFolderViewItem* cur_item, LLInventoryItem* inv_item, const LLParcelData& parcel_data); - void doCreatePick(LLLandmark* landmark); private: - LLPlacesInventoryPanel* mFavoritesInventoryPanel; LLPlacesInventoryPanel* mLandmarksInventoryPanel; - LLPlacesInventoryPanel* mMyInventoryPanel; - LLPlacesInventoryPanel* mLibraryInventoryPanel; - LLMenuButton* mGearButton; LLToggleableMenu* mGearLandmarkMenu; LLToggleableMenu* mGearFolderMenu; - LLMenuGL* mMenuAdd; - LLPlacesInventoryPanel* mCurrentSelectedList; - LLInventoryObserver* mInventoryObserver; + LLToggleableMenu* mSortingMenu; + LLToggleableMenu* mAddMenu; - LLPanel* mListCommands; + bool isLandmarksPanel; - typedef std::vector<LLAccordionCtrlTab*> accordion_tabs_t; - accordion_tabs_t mAccordionTabs; + LLUUID mCreatePickItemId; // item we requested a pick for +}; - LLAccordionCtrlTab* mMyLandmarksAccordionTab; + +class LLFavoritesPanel : public LLLandmarksPanel +{ +public: + LLFavoritesPanel(); + + BOOL postBuild() override; + void initFavoritesInventoryPanel(); }; #endif //LL_LLPANELLANDMARKS_H diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index fbc1b80857..e9c9c451a2 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -115,6 +115,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) mSavedFolderState(NULL), mFilterText(""), mMenuGearDefault(NULL), + mMenuVisibility(NULL), mMenuAddHandle(), mNeedUploadCost(true) { @@ -219,6 +220,17 @@ BOOL LLPanelMainInventory::postBuild() recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER)); } } + if(mActivePanel) + { + if(savedFilterState.has(mActivePanel->getFilter().getName())) + { + LLSD items = savedFilterState.get(mActivePanel->getFilter().getName()); + LLInventoryFilter::Params p; + LLParamSDParser parser; + parser.readSD(items, p); + mActivePanel->getFilter().setSearchVisibilityTypes(p); + } + } } @@ -229,6 +241,7 @@ BOOL LLPanelMainInventory::postBuild() } mGearMenuButton = getChild<LLMenuButton>("options_gear_btn"); + mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn"); initListCommandsHandlers(); @@ -254,6 +267,9 @@ BOOL LLPanelMainInventory::postBuild() LLPanelMainInventory::~LLPanelMainInventory( void ) { // Save the filters state. + // Some params types cannot be saved this way + // for example, LLParamSDParser doesn't know about U64, + // so some FilterOps params should be revised. LLSD filterRoot; LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items"); if (all_items_panel) @@ -1165,6 +1181,10 @@ void LLPanelMainInventory::initListCommandsHandlers() LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mMenuAddHandle = menu->getHandle(); + mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mVisibilityMenuButton->setMenu(mMenuVisibility); + mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT); + // Update the trash button when selected item(s) get worn or taken off. LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this)); } @@ -1354,6 +1374,21 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) } LLFloaterReg::showInstance("linkreplace", params); } + + if (command_name == "toggle_search_trash") + { + mActivePanel->getFilter().toggleSearchVisibilityTrash(); + } + + if (command_name == "toggle_search_library") + { + mActivePanel->getFilter().toggleSearchVisibilityLibrary(); + } + + if (command_name == "include_links") + { + mActivePanel->getFilter().toggleSearchVisibilityLinks(); + } } void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility ) @@ -1499,6 +1534,21 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata) return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; } + if (command_name == "toggle_search_trash") + { + return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0; + } + + if (command_name == "toggle_search_library") + { + return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0; + } + + if (command_name == "include_links") + { + return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0; + } + return FALSE; } diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index a6bdee233d..dfb8db9d12 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -93,6 +93,8 @@ public: void toggleFindOptions(); + void resetFilters(); + protected: // // Misc functions @@ -117,7 +119,6 @@ protected: void doToSelected(const LLSD& userdata); void closeAllFolders(); void doCreate(const LLSD& userdata); - void resetFilters(); void setSortBy(const LLSD& userdata); void saveTexture(const LLSD& userdata); bool isSaveTextureEnabled(const LLSD& userdata); @@ -169,7 +170,9 @@ protected: private: LLDragAndDropButton* mTrashButton; LLToggleableMenu* mMenuGearDefault; + LLToggleableMenu* mMenuVisibility; LLMenuButton* mGearMenuButton; + LLMenuButton* mVisibilityMenuButton; LLHandle<LLView> mMenuAddHandle; bool mNeedUploadCost; diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 28a020870f..5be9ab6095 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -58,7 +58,6 @@ #include "llmenubutton.h" #include "llpaneloutfitsinventory.h" #include "lluiconstants.h" -#include "llsaveoutfitcombobtn.h" #include "llscrolllistctrl.h" #include "lltextbox.h" #include "lltoggleablemenu.h" @@ -80,6 +79,8 @@ const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LL const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK; static const std::string REVERT_BTN("revert_btn"); +static const std::string SAVE_AS_BTN("save_as_btn"); +static const std::string SAVE_BTN("save_btn"); /////////////////////////////////////////////////////////////////////////////// @@ -562,7 +563,8 @@ BOOL LLPanelOutfitEdit::postBuild() mGearMenu = LLPanelOutfitEditGearMenu::create(); mGearMenuBtn->setMenu(mGearMenu); - mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this)); + getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false)); + getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true)); onOutfitChanging(gAgentWearables.isCOFChangeInProgress()); return TRUE; @@ -1239,11 +1241,9 @@ void LLPanelOutfitEdit::updateVerbs() bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked(); bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull(); - mSaveComboBtn->setSaveBtnEnabled(!outfit_locked && outfit_is_dirty); + getChildView(SAVE_BTN)->setEnabled(!outfit_locked && outfit_is_dirty); getChildView(REVERT_BTN)->setEnabled(outfit_is_dirty && has_baseoutfit); - mSaveComboBtn->setMenuItemEnabled("save_outfit", !outfit_locked && outfit_is_dirty); - mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing")); updateCurrentOutfitName(); @@ -1429,4 +1429,13 @@ void LLPanelOutfitEdit::saveListSelection() } } +void LLPanelOutfitEdit::saveOutfit(bool as_new) +{ + LLPanelOutfitsInventory* panel_outfits_inventory = LLPanelOutfitsInventory::findInstance(); + if (panel_outfits_inventory) + { + panel_outfits_inventory->saveOutfit(as_new); + } +} + // EOF diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 3c6efac0e7..d0597fb72b 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -58,7 +58,6 @@ class LLMenuButton; class LLMenuGL; class LLFindNonLinksByMask; class LLFindWearablesOfType; -class LLSaveOutfitComboBtn; class LLWearableItemTypeNameComparator; class LLPanelOutfitEdit : public LLPanel @@ -195,6 +194,7 @@ private: void getSelectedItemsUUID(uuid_vec_t& uuid_list); void getCurrentItemUUID(LLUUID& selected_id); void onCOFChanged(); + void saveOutfit(bool as_new = false); /** * Method preserves selection while switching between folder/list view modes @@ -237,7 +237,6 @@ private: LLToggleableMenu* mGearMenu; LLToggleableMenu* mAddWearablesGearMenu; bool mInitialized; - std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; LLMenuButton* mWearablesGearMenuBtn; LLMenuButton* mGearMenuBtn; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 8fff52ca4e..531073526b 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -40,7 +40,6 @@ #include "lloutfitgallery.h" #include "lloutfitslist.h" #include "llpanelwearing.h" -#include "llsaveoutfitcombobtn.h" #include "llsidepanelappearance.h" #include "llviewercontrol.h" #include "llviewerfoldertype.h" @@ -49,6 +48,9 @@ static const std::string OUTFITS_TAB_NAME = "outfitslist_tab"; static const std::string OUTFIT_GALLERY_TAB_NAME = "outfit_gallery_tab"; static const std::string COF_TAB_NAME = "cof_tab"; +static const std::string SAVE_AS_BTN("save_as_btn"); +static const std::string SAVE_BTN("save_btn"); + static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory"); LLPanelOutfitsInventory::LLPanelOutfitsInventory() : @@ -90,8 +92,9 @@ BOOL LLPanelOutfitsInventory::postBuild() { LLInventoryModelBackgroundFetch::instance().start(outfits_cat); } - - mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this, true)); + + getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, false)); + getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, true)); return TRUE; } @@ -246,6 +249,12 @@ LLPanelOutfitsInventory* LLPanelOutfitsInventory::findInstance() return dynamic_cast<LLPanelOutfitsInventory*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfits_inventory")); } +void LLPanelOutfitsInventory::openApearanceTab(const std::string& tab_name) +{ + if (!mAppearanceTabs) return; + mAppearanceTabs->selectTabByName(tab_name); +} + ////////////////////////////////////////////////////////////////////////////////// // List Commands // @@ -269,7 +278,7 @@ void LLPanelOutfitsInventory::updateListCommands() mOutfitGalleryPanel->childSetEnabled("trash_btn", trash_enabled); wear_btn->setEnabled(wear_enabled); wear_btn->setVisible(wear_visible); - mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled); + getChild<LLButton>(SAVE_BTN)->setEnabled(make_outfit_enabled); wear_btn->setToolTip(getString((!isOutfitsGalleryPanelActive() && mMyOutfitsPanel->hasItemSelected()) ? "wear_items_tooltip" : "wear_outfit_tooltip")); } @@ -368,3 +377,15 @@ LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP() dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance")); return panel_appearance; } + +void LLPanelOutfitsInventory::saveOutfit(bool as_new) +{ + if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit()) + { + // we don't need to ask for an outfit name, and updateBaseOutfit() successfully saved. + // If updateBaseOutfit fails, ask for an outfit name anyways + return; + } + + onSave(); +} diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 6a0ea04fa6..50d7074d4b 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -38,7 +38,6 @@ class LLPanelWearing; class LLMenuGL; class LLSidepanelAppearance; class LLTabContainer; -class LLSaveOutfitComboBtn; class LLPanelOutfitsInventory : public LLPanel { @@ -52,6 +51,7 @@ public: void onSearchEdit(const std::string& string); void onSave(); + void saveOutfit(bool as_new = false); bool onSaveCommit(const LLSD& notification, const LLSD& response); @@ -59,13 +59,14 @@ public: static LLPanelOutfitsInventory* findInstance(); + void openApearanceTab(const std::string& tab_name); + protected: void updateVerbs(); private: LLTabContainer* mAppearanceTabs; std::string mFilterSubString; - std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; ////////////////////////////////////////////////////////////////////////////////// // tab panels // diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index e5142f2b5f..5997d522c4 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -661,6 +661,7 @@ BOOL LLPanelPeople::postBuild() mRecentList->setShowIcons("RecentListShowIcons"); mGroupList = getChild<LLGroupList>("group_list"); + mGroupList->setNoItemsCommentText(getString("no_groups_msg")); mGroupList->setNoItemsMsg(getString("no_groups_msg")); mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg")); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 53870fb5c7..9c67ec40fe 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -53,6 +53,7 @@ #include "llagentpicksinfo.h" #include "llavatarpropertiesprocessor.h" #include "llcommandhandler.h" +#include "lldndbutton.h" #include "llfloaterworldmap.h" #include "llinventorybridge.h" #include "llinventoryobserver.h" @@ -79,6 +80,7 @@ static const F32 PLACE_INFO_UPDATE_INTERVAL = 3.0; static const std::string AGENT_INFO_TYPE = "agent"; static const std::string CREATE_LANDMARK_INFO_TYPE = "create_landmark"; +static const std::string CREATE_PICK_TYPE = "create_pick"; static const std::string LANDMARK_INFO_TYPE = "landmark"; static const std::string REMOTE_PLACE_INFO_TYPE = "remote_place"; static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history"; @@ -293,8 +295,25 @@ BOOL LLPanelPlaces::postBuild() mOverflowBtn = getChild<LLMenuButton>("overflow_btn"); mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this)); - mPlaceInfoBtn = getChild<LLButton>("profile_btn"); - mPlaceInfoBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onProfileButtonClicked, this)); + mGearMenuButton = getChild<LLMenuButton>("options_gear_btn"); + mGearMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onGearMenuClick, this)); + + mSortingMenuButton = getChild<LLMenuButton>("sorting_menu_btn"); + mSortingMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onSortingMenuClick, this)); + + mAddMenuButton = getChild<LLMenuButton>("add_menu_btn"); + mAddMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onAddMenuClick, this)); + + mRemoveSelectedBtn = getChild<LLButton>("trash_btn"); + mRemoveSelectedBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onRemoveButtonClicked, this)); + + LLDragAndDropButton* trash_btn = (LLDragAndDropButton*)mRemoveSelectedBtn; + trash_btn->setDragAndDropHandler(boost::bind(&LLPanelPlaces::handleDragAndDropToTrash, this + , _4 // BOOL drop + , _5 // EDragAndDropType cargo_type + , _6 // void* cargo_data + , _7 // EAcceptance* accept + )); LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("Places.OverflowMenu.Action", boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2)); @@ -323,6 +342,10 @@ BOOL LLPanelPlaces::postBuild() mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this)); } + mButtonsContainer = getChild<LLPanel>("button_layout_panel"); + mButtonsContainer->setVisible(FALSE); + mFilterContainer = getChild<LLLayoutStack>("top_menu_panel"); + mFilterEditor = getChild<LLFilterEditor>("Filter"); if (mFilterEditor) { @@ -388,7 +411,22 @@ void LLPanelPlaces::onOpen(const LLSD& key) // Update the buttons at the bottom of the panel updateVerbs(); } - else + else if (key_type == CREATE_PICK_TYPE) + { + LLUUID item_id = key["item_id"]; + + LLLandmarksPanel* landmarks_panel = + dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks")); + if (landmarks_panel && item_id.notNull()) + { + LLLandmark* landmark = LLLandmarkActions::getLandmark(item_id, boost::bind(&LLLandmarksPanel::doCreatePick, landmarks_panel, _1, item_id)); + if (landmark) + { + landmarks_panel->doCreatePick(landmark, item_id); + } + } + } + else // "create_landmark" { mFilterEditor->clear(); onFilterEdit("", false); @@ -409,7 +447,8 @@ void LLPanelPlaces::onOpen(const LLSD& key) } else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) { - mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); + LLUUID dest_folder = key["dest_folder"]; + mLandmarkInfo->setInfoAndCreateLandmark(dest_folder); if (key.has("x") && key.has("y") && key.has("z")) { @@ -612,6 +651,23 @@ void LLPanelPlaces::onTabSelected() onFilterEdit(mActivePanel->getFilterSubString(), true); mActivePanel->updateVerbs(); + + // History panel does not support deletion nor creation + // Hide menus + bool supports_create = mActivePanel->getCreateMenu() != NULL; + childSetVisible("add_btn_panel", supports_create); + + // favorites and inventory can remove items, history can clear history + childSetVisible("trash_btn_panel", TRUE); + + if (supports_create) + { + mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items")); + } + else + { + mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history")); + } } void LLPanelPlaces::onTeleportButtonClicked() @@ -728,34 +784,6 @@ void LLPanelPlaces::onEditButtonClicked() updateVerbs(); } -class LLUpdateLandmarkParent : public LLInventoryCallback -{ -public: - LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) : - mItem(item), - mNewParentId(new_parent) - {}; - /* virtual */ void fire(const LLUUID& inv_item_id) - { - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - - mItem->setParent(mNewParentId); - mItem->updateParentOnServer(FALSE); - - gInventory.updateItem(mItem); - gInventory.notifyObservers(); - } - -private: - LLPointer<LLViewerInventoryItem> mItem; - LLUUID mNewParentId; -}; - void LLPanelPlaces::onSaveButtonClicked() { if (!mLandmarkInfo || mItem.isNull()) @@ -885,14 +913,6 @@ void LLPanelPlaces::onOverflowButtonClicked() mOverflowBtn->setMenu(menu, LLMenuButton::MP_TOP_RIGHT); } -void LLPanelPlaces::onProfileButtonClicked() -{ - if (!mActivePanel) - return; - - mActivePanel->onShowProfile(); -} - bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param) { std::string value = param.asString(); @@ -981,6 +1001,50 @@ void LLPanelPlaces::onBackButtonClicked() updateVerbs(); } +void LLPanelPlaces::onGearMenuClick() +{ + if (mActivePanel) + { + LLToggleableMenu* menu = mActivePanel->getSelectionMenu(); + mGearMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); + } +} + +void LLPanelPlaces::onSortingMenuClick() +{ + if (mActivePanel) + { + LLToggleableMenu* menu = mActivePanel->getSortingMenu(); + mSortingMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); + } +} + +void LLPanelPlaces::onAddMenuClick() +{ + if (mActivePanel) + { + LLToggleableMenu* menu = mActivePanel->getCreateMenu(); + mAddMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); + } +} + +void LLPanelPlaces::onRemoveButtonClicked() +{ + if (mActivePanel) + { + mActivePanel->onRemoveSelected(); + } +} + +bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) +{ + if (mActivePanel) + { + return mActivePanel->handleDragAndDropToTrash(drop, cargo_type, cargo_data, accept); + } + return false; +} + void LLPanelPlaces::togglePickPanel(BOOL visible) { if (mPickPanel) @@ -997,8 +1061,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) if (!mPlaceProfile || !mLandmarkInfo) return; - mFilterEditor->setVisible(!visible); mTabContainer->setVisible(!visible); + mButtonsContainer->setVisible(visible); + mFilterContainer->setVisible(!visible); if (mPlaceInfoType == AGENT_INFO_TYPE || mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || @@ -1014,10 +1079,6 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) // to avoid text blinking. mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL); - LLRect rect = getRect(); - LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom); - mPlaceProfile->reshape(new_rect.getWidth(), new_rect.getHeight()); - mLandmarkInfo->setVisible(FALSE); } else if (mPlaceInfoType == AGENT_INFO_TYPE) @@ -1038,15 +1099,19 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) if (visible) { mLandmarkInfo->resetLocation(); - - LLRect rect = getRect(); - LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom); - mLandmarkInfo->reshape(new_rect.getWidth(), new_rect.getHeight()); } else { - LLLandmarksPanel* landmarks_panel = - dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks")); + std::string tab_panel_name("Landmarks"); + if (mItem.notNull()) + { + if (gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE))) + { + tab_panel_name = "Favorites"; + } + } + + LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName(tab_panel_name)); if (landmarks_panel) { // If a landmark info is being closed we open the landmarks tab @@ -1056,6 +1121,10 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) { landmarks_panel->setItemSelected(mItem->getUUID(), TRUE); } + else + { + landmarks_panel->resetSelection(); + } } } } @@ -1123,11 +1192,19 @@ void LLPanelPlaces::createTabs() if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance() && !mTabsCreated)) return; + LLFavoritesPanel* favorites_panel = new LLFavoritesPanel(); + if (favorites_panel) + { + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(favorites_panel). + label(getString("favorites_tab_title")). + insert_at(LLTabContainer::END)); + } + LLLandmarksPanel* landmarks_panel = new LLLandmarksPanel(); if (landmarks_panel) { - landmarks_panel->setPanelPlacesButtons(this); - mTabContainer->addTabPanel( LLTabContainer::TabPanelParams(). panel(landmarks_panel). @@ -1138,8 +1215,6 @@ void LLPanelPlaces::createTabs() LLTeleportHistoryPanel* teleport_history_panel = new LLTeleportHistoryPanel(); if (teleport_history_panel) { - teleport_history_panel->setPanelPlacesButtons(this); - mTabContainer->addTabPanel( LLTabContainer::TabPanelParams(). panel(teleport_history_panel). @@ -1151,9 +1226,31 @@ void LLPanelPlaces::createTabs() mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel()); - // Filter applied to show all items. - if (mActivePanel) - mActivePanel->onSearchEdit(mActivePanel->getFilterSubString()); + if (mActivePanel) + { + // Filter applied to show all items. + mActivePanel->onSearchEdit(mActivePanel->getFilterSubString()); + + // History panel does not support deletion nor creation + // Hide menus + bool supports_create = mActivePanel->getCreateMenu() != NULL; + childSetVisible("add_btn_panel", supports_create); + + // favorites and inventory can remove items, history can clear history + childSetVisible("trash_btn_panel", TRUE); + + if (supports_create) + { + mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items")); + } + else + { + mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history")); + } + + mActivePanel->setRemoveBtn(mRemoveSelectedBtn); + mActivePanel->updateVerbs(); + } mTabsCreated = true; } @@ -1219,15 +1316,12 @@ void LLPanelPlaces::updateVerbs() mSaveBtn->setVisible(isLandmarkEditModeOn); mCancelBtn->setVisible(isLandmarkEditModeOn); mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn); - mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible); bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn; mOverflowBtn->setVisible(show_options_btn); getChild<LLLayoutPanel>("lp_options")->setVisible(show_options_btn); getChild<LLLayoutPanel>("lp2")->setVisible(!show_options_btn); - mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos); - if (is_place_info_visible) { mShowOnMapBtn->setEnabled(have_3d_pos); diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 978b030b2e..3b87eb6cb9 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -48,6 +48,7 @@ class LLRemoteParcelInfoObserver; class LLTabContainer; class LLToggleableMenu; class LLMenuButton; +class LLLayoutStack; typedef std::pair<LLUUID, std::string> folder_pair_t; @@ -96,7 +97,12 @@ private: bool onOverflowMenuItemEnable(const LLSD& param); void onCreateLandmarkButtonClicked(const LLUUID& folder_id); void onBackButtonClicked(); - void onProfileButtonClicked(); + void onGearMenuClick(); + void onSortingMenuClick(); + void onAddMenuClick(); + void onRemoveButtonClicked(); + bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept); + void toggleMediaPanel(); void togglePickPanel(BOOL visible); @@ -111,6 +117,8 @@ private: LLFilterEditor* mFilterEditor; LLPanelPlacesTab* mActivePanel; LLTabContainer* mTabContainer; + LLPanel* mButtonsContainer; + LLLayoutStack* mFilterContainer; LLPanelPlaceProfile* mPlaceProfile; LLPanelLandmarkInfo* mLandmarkInfo; @@ -125,7 +133,12 @@ private: LLButton* mCancelBtn; LLButton* mCloseBtn; LLMenuButton* mOverflowBtn; - LLButton* mPlaceInfoBtn; + + // Top menu + LLMenuButton* mGearMenuButton; + LLMenuButton* mSortingMenuButton; + LLMenuButton* mAddMenuButton; + LLButton* mRemoveSelectedBtn; LLPlacesInventoryObserver* mInventoryObserver; LLPlacesParcelObserver* mParcelObserver; diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp index 9644b7518e..748a917147 100644 --- a/indra/newview/llpanelplacestab.cpp +++ b/indra/newview/llpanelplacestab.cpp @@ -38,6 +38,7 @@ #include "llworldmap.h" std::string LLPanelPlacesTab::sFilterSubString = LLStringUtil::null; +LLButton* LLPanelPlacesTab::sRemoveBtn = NULL; bool LLPanelPlacesTab::isTabVisible() { @@ -47,13 +48,6 @@ bool LLPanelPlacesTab::isTabVisible() return true; } -void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel) -{ - mTeleportBtn = panel->getChild<LLButton>("teleport_btn"); - mShowOnMapBtn = panel->getChild<LLButton>("map_btn"); - mShowProfile = panel->getChild<LLButton>("profile_btn"); -} - void LLPanelPlacesTab::onRegionResponse(const LLVector3d& landmark_global_pos, U64 region_handle, const std::string& url, diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h index 367ce46e2e..aab1c130c1 100644 --- a/indra/newview/llpanelplacestab.h +++ b/indra/newview/llpanelplacestab.h @@ -30,6 +30,7 @@ #include "llpanel.h" class LLPanelPlaces; +class LLToggleableMenu; class LLPanelPlacesTab : public LLPanel { @@ -42,11 +43,21 @@ public: virtual void onShowOnMap() = 0; virtual void onShowProfile() = 0; virtual void onTeleport() = 0; + virtual void onRemoveSelected() = 0; virtual bool isSingleItemSelected() = 0; + // returns menu for current selection + virtual LLToggleableMenu* getSelectionMenu() = 0; + virtual LLToggleableMenu* getSortingMenu() = 0; + virtual LLToggleableMenu* getCreateMenu() = 0; + + /** + * Processes drag-n-drop of the Landmarks and folders into trash button. + */ + virtual bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) = 0; + bool isTabVisible(); // Check if parent TabContainer is visible. - void setPanelPlacesButtons(LLPanelPlaces* panel); void onRegionResponse(const LLVector3d& landmark_global_pos, U64 region_handle, const std::string& url, @@ -56,13 +67,12 @@ public: const std::string& getFilterSubString() { return sFilterSubString; } void setFilterSubString(const std::string& string) { sFilterSubString = string; } -protected: - LLButton* mTeleportBtn; - LLButton* mShowOnMapBtn; - LLButton* mShowProfile; + void setRemoveBtn(LLButton* trash_btn) { sRemoveBtn = trash_btn; } +protected: // Search string for filtering landmarks and teleport history locations static std::string sFilterSubString; + static LLButton* sRemoveBtn; }; #endif //LL_LLPANELPLACESTAB_H diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index fe0608d544..b938b30479 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -56,7 +56,7 @@ static const std::string COLLAPSED_BY_USER = "collapsed_by_user"; class LLTeleportHistoryFlatItem : public LLPanel { public: - LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, + LLTeleportHistoryFlatItem(S32 index, LLToggleableMenu *menu, const std::string ®ion_name, LLDate date, const std::string &hl); virtual ~LLTeleportHistoryFlatItem(); @@ -86,12 +86,13 @@ public: private: void onProfileBtnClick(); + void showMenu(S32 x, S32 y); LLButton* mProfileBtn; LLTextBox* mTitle; LLTextBox* mTimeTextBox; - LLTeleportHistoryPanel::ContextMenu *mContextMenu; + LLToggleableMenu *mMenu; S32 mIndex; std::string mRegionName; @@ -112,7 +113,7 @@ protected: public: LLTeleportHistoryFlatItem* getFlatItemForPersistentItem ( - LLTeleportHistoryPanel::ContextMenu *context_menu, + LLToggleableMenu *menu, const LLTeleportHistoryPersistentItem& persistent_item, const S32 cur_item_index, const std::string &hl); @@ -130,16 +131,16 @@ private: //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, +LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLToggleableMenu *menu, const std::string ®ion_name, LLDate date, const std::string &hl) : LLPanel(), mIndex(index), - mContextMenu(context_menu), + mMenu(menu), mRegionName(region_name), mDate(date), mHighlight(hl) { - buildFromFile( "panel_teleport_history_item.xml"); + buildFromFile("panel_teleport_history_item.xml"); } LLTeleportHistoryFlatItem::~LLTeleportHistoryFlatItem() @@ -266,10 +267,9 @@ void LLTeleportHistoryFlatItem::onMouseLeave(S32 x, S32 y, MASK mask) // virtual BOOL LLTeleportHistoryFlatItem::handleRightMouseDown(S32 x, S32 y, MASK mask) { - if (mContextMenu) - mContextMenu->show(this, mIndex, x, y); - - return LLPanel::handleRightMouseDown(x, y, mask); + LLPanel::handleRightMouseDown(x, y, mask); + showMenu(x, y); + return TRUE; } void LLTeleportHistoryFlatItem::showPlaceInfoPanel(S32 index) @@ -286,13 +286,23 @@ void LLTeleportHistoryFlatItem::onProfileBtnClick() LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex); } +void LLTeleportHistoryFlatItem::showMenu(S32 x, S32 y) +{ + mMenu->setButtonRect(this); + mMenu->buildDrawLabels(); + mMenu->arrangeAndClear(); + mMenu->updateParent(LLMenuGL::sMenuContainer); + + LLMenuGL::showPopup(this, mMenu, x, y); +} + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// LLTeleportHistoryFlatItem* LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem ( - LLTeleportHistoryPanel::ContextMenu *context_menu, + LLToggleableMenu *menu, const LLTeleportHistoryPersistentItem& persistent_item, const S32 cur_item_index, const std::string &hl) @@ -321,7 +331,7 @@ LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem ( if ( !item ) { item = new LLTeleportHistoryFlatItem(cur_item_index, - context_menu, + menu, persistent_item.mTitle, persistent_item.mDate, hl); @@ -365,74 +375,6 @@ void LLTeleportHistoryFlatItemStorage::purge() //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -LLTeleportHistoryPanel::ContextMenu::ContextMenu() : - mMenu(NULL), mIndex(0) -{ -} - -void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, S32 x, S32 y) -{ - if (mMenu) - { - //preventing parent (menu holder) from deleting already "dead" context menus on exit - LLView* parent = mMenu->getParent(); - if (parent) - { - parent->removeChild(mMenu); - } - delete mMenu; - } - - mIndex = index; - mMenu = createMenu(); - - mMenu->show(x, y); - LLMenuGL::showPopup(spawning_view, mMenu, x, y); -} - -LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu() -{ - // set up the callbacks for all of the avatar menu items - // (N.B. callbacks don't take const refs as mID is local scope) - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - - registrar.add("TeleportHistory.Teleport", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this)); - registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this)); - registrar.add("TeleportHistory.CopyToClipboard",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard, this)); - - // create the context menu from the XUI - llassert(LLMenuGL::sMenuContainer != NULL); - return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( - "menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLTeleportHistoryPanel::ContextMenu::onTeleport() -{ - confirmTeleport(mIndex); -} - -void LLTeleportHistoryPanel::ContextMenu::onInfo() -{ - LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex); -} - -//static -void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl) -{ - LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size()); - - LLSD args; - args["SLURL"] = slurl; - - LLNotificationsUtil::add("CopySLURL", args); -} - -void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard() -{ - LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos; - LLLandmarkActions::getSLURLfromPosGlobal(globalPos, - boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1)); -} // Not yet implemented; need to remove buildPanel() from constructor when we switch //static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history"); @@ -446,7 +388,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() mAccordionTabMenu(NULL), mLastSelectedFlatlList(NULL), mLastSelectedItemIndex(-1), - mMenuGearButton(NULL) + mGearItemMenu(NULL), + mSortingMenu(NULL) { buildFromFile( "panel_teleport_history.xml"); } @@ -454,12 +397,19 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() LLTeleportHistoryPanel::~LLTeleportHistoryPanel() { LLTeleportHistoryFlatItemStorage::instance().purge(); - if (mGearMenuHandle.get()) mGearMenuHandle.get()->die(); mTeleportHistoryChangedConnection.disconnect(); } BOOL LLTeleportHistoryPanel::postBuild() { + mCommitCallbackRegistrar.add("TeleportHistory.GearMenu.Action", boost::bind(&LLTeleportHistoryPanel::onGearMenuAction, this, _2)); + mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2)); + + // init menus before list, since menus are passed to list + mGearItemMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_item.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mGearItemMenu->setAlwaysShowMenu(TRUE); // all items can be disabled if nothing is selected, show anyway + mSortingMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mTeleportHistory = LLTeleportHistoryStorage::getInstance(); if (mTeleportHistory) { @@ -511,22 +461,6 @@ BOOL LLTeleportHistoryPanel::postBuild() } } - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - - registrar.add("TeleportHistory.ExpandAllFolders", boost::bind(&LLTeleportHistoryPanel::onExpandAllFolders, this)); - registrar.add("TeleportHistory.CollapseAllFolders", boost::bind(&LLTeleportHistoryPanel::onCollapseAllFolders, this)); - registrar.add("TeleportHistory.ClearTeleportHistory", boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistory, this)); - mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2)); - - mMenuGearButton = getChild<LLMenuButton>("gear_btn"); - - LLToggleableMenu* gear_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());; - if(gear_menu) - { - mGearMenuHandle = gear_menu->getHandle(); - mMenuGearButton->setMenu(gear_menu); - } - return TRUE; } @@ -600,6 +534,12 @@ void LLTeleportHistoryPanel::onTeleport() confirmTeleport(itemp->getIndex()); } +// virtual +void LLTeleportHistoryPanel::onRemoveSelected() +{ + LLNotificationsUtil::add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2)); +} + /* // virtual void LLTeleportHistoryPanel::onCopySLURL() @@ -630,19 +570,28 @@ void LLTeleportHistoryPanel::updateVerbs() if (!isTabVisible()) return; - if (!mLastSelectedFlatlList) + if (sRemoveBtn) { - mTeleportBtn->setEnabled(false); - mShowProfile->setEnabled(false); - mShowOnMapBtn->setEnabled(false); - return; + sRemoveBtn->setEnabled(true); } +} - LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); +// virtual +LLToggleableMenu* LLTeleportHistoryPanel::getSelectionMenu() +{ + return mGearItemMenu; +} + +// virtual +LLToggleableMenu* LLTeleportHistoryPanel::getSortingMenu() +{ + return mSortingMenu; +} - mTeleportBtn->setEnabled(NULL != itemp); - mShowProfile->setEnabled(NULL != itemp); - mShowOnMapBtn->setEnabled(NULL != itemp); +// virtual +LLToggleableMenu* LLTeleportHistoryPanel::getCreateMenu() +{ + return NULL; } void LLTeleportHistoryPanel::getNextTab(const LLDate& item_date, S32& tab_idx, LLDate& tab_date) @@ -778,7 +727,7 @@ void LLTeleportHistoryPanel::refresh() { LLTeleportHistoryFlatItem* item = LLTeleportHistoryFlatItemStorage::instance() - .getFlatItemForPersistentItem(&mContextMenu, + .getFlatItemForPersistentItem(mGearItemMenu, items[mCurrentItem], mCurrentItem, filter_string); @@ -847,7 +796,7 @@ void LLTeleportHistoryPanel::replaceItem(S32 removed_index) const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems(); LLTeleportHistoryFlatItem* item = LLTeleportHistoryFlatItemStorage::instance() - .getFlatItemForPersistentItem(&mContextMenu, + .getFlatItemForPersistentItem(mGearItemMenu, history_items[history_items.size() - 1], // Most recent item, it was added instead of removed history_items.size(), // index will be decremented inside loop below sFilterSubString); @@ -1019,38 +968,6 @@ void LLTeleportHistoryPanel::onAccordionTabClose(LLAccordionCtrlTab *tab) mHistoryAccordion->arrange(); } -void LLTeleportHistoryPanel::onExpandAllFolders() -{ - S32 tabs_cnt = mItemContainers.size(); - - for (S32 n = 0; n < tabs_cnt; n++) - { - mItemContainers.at(n)->setDisplayChildren(true); - } - mHistoryAccordion->arrange(); -} - -void LLTeleportHistoryPanel::onCollapseAllFolders() -{ - S32 tabs_cnt = mItemContainers.size(); - - for (S32 n = 0; n < tabs_cnt; n++) - { - mItemContainers.at(n)->setDisplayChildren(false); - } - mHistoryAccordion->arrange(); - - if (mLastSelectedFlatlList) - { - mLastSelectedFlatlList->resetSelection(); - } -} - -void LLTeleportHistoryPanel::onClearTeleportHistory() -{ - LLNotificationsUtil::add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2)); -} - bool LLTeleportHistoryPanel::onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response) { @@ -1082,45 +999,137 @@ LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTa return NULL; } -bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const +void LLTeleportHistoryPanel::gotSLURLCallback(const std::string& slurl) { - S32 tabs_cnt = mItemContainers.size(); - - bool has_expanded_tabs = false; - bool has_collapsed_tabs = false; - - for (S32 n = 0; n < tabs_cnt; n++) - { - LLAccordionCtrlTab* tab = mItemContainers.at(n); - if (!tab->getVisible()) - continue; - - if (tab->getDisplayChildren()) - { - has_expanded_tabs = true; - } - else - { - has_collapsed_tabs = true; - } + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl), 0, slurl.size()); - if (has_expanded_tabs && has_collapsed_tabs) - { - break; - } - } + LLSD args; + args["SLURL"] = slurl; - std::string command_name = userdata.asString(); + LLNotificationsUtil::add("CopySLURL", args); +} - if (has_expanded_tabs && command_name == "collapse_all") - { - return true; - } +void LLTeleportHistoryPanel::onGearMenuAction(const LLSD& userdata) +{ + std::string command_name = userdata.asString(); + + if ("expand_all" == command_name) + { + S32 tabs_cnt = mItemContainers.size(); + + for (S32 n = 0; n < tabs_cnt; n++) + { + mItemContainers.at(n)->setDisplayChildren(true); + } + mHistoryAccordion->arrange(); + } + else if ("collapse_all" == command_name) + { + S32 tabs_cnt = mItemContainers.size(); + + for (S32 n = 0; n < tabs_cnt; n++) + { + mItemContainers.at(n)->setDisplayChildren(false); + } + mHistoryAccordion->arrange(); + + if (mLastSelectedFlatlList) + { + mLastSelectedFlatlList->resetSelection(); + } + } + + S32 index = -1; + if (mLastSelectedFlatlList) + { + LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); + if (itemp) + { + index = itemp->getIndex(); + } + } + + if ("teleport" == command_name) + { + confirmTeleport(index); + } + else if ("view" == command_name) + { + LLTeleportHistoryFlatItem::showPlaceInfoPanel(index); + } + else if ("show_on_map" == command_name) + { + LLTeleportHistoryStorage::getInstance()->showItemOnMap(index); + } + else if ("copy_slurl" == command_name) + { + LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[index].mGlobalPos; + LLLandmarkActions::getSLURLfromPosGlobal(globalPos, + boost::bind(&LLTeleportHistoryPanel::gotSLURLCallback, _1)); + } +} - if (has_collapsed_tabs && command_name == "expand_all") - { - return true; - } +bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const +{ + std::string command_name = userdata.asString(); + + if (command_name == "collapse_all" + || command_name == "expand_all") + { + S32 tabs_cnt = mItemContainers.size(); + + bool has_expanded_tabs = false; + bool has_collapsed_tabs = false; + + for (S32 n = 0; n < tabs_cnt; n++) + { + LLAccordionCtrlTab* tab = mItemContainers.at(n); + if (!tab->getVisible()) + continue; + + if (tab->getDisplayChildren()) + { + has_expanded_tabs = true; + } + else + { + has_collapsed_tabs = true; + } + + if (has_expanded_tabs && has_collapsed_tabs) + { + break; + } + } + + if (command_name == "collapse_all") + { + return has_expanded_tabs; + } + + if (command_name == "expand_all") + { + return has_collapsed_tabs; + } + } + + if (command_name == "clear_history") + { + return mTeleportHistory->getItems().size() > 0; + } + + if ("teleport" == command_name + || "view" == command_name + || "show_on_map" == command_name + || "copy_slurl" == command_name) + { + if (!mLastSelectedFlatlList) + { + return false; + } + LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); + return itemp != NULL; + } return false; } diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index b88861c5c6..058fee0170 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -43,38 +43,26 @@ class LLMenuButton; class LLTeleportHistoryPanel : public LLPanelPlacesTab { public: - // *TODO: derive from LLListContextMenu? - class ContextMenu - { - public: - ContextMenu(); - void show(LLView* spawning_view, S32 index, S32 x, S32 y); - - private: - LLContextMenu* createMenu(); - void onTeleport(); - void onInfo(); - void onCopyToClipboard(); - - static void gotSLURLCallback(const std::string& slurl); - - LLContextMenu* mMenu; - S32 mIndex; - }; - LLTeleportHistoryPanel(); virtual ~LLTeleportHistoryPanel(); - /*virtual*/ BOOL postBuild(); - /*virtual*/ void draw(); + BOOL postBuild() override; + void draw() override; - /*virtual*/ void onSearchEdit(const std::string& string); - /*virtual*/ void onShowOnMap(); - /*virtual*/ void onShowProfile(); - /*virtual*/ void onTeleport(); - ///*virtual*/ void onCopySLURL(); - /*virtual*/ void updateVerbs(); - /*virtual*/ bool isSingleItemSelected(); + void onSearchEdit(const std::string& string) override; + void onShowOnMap() override; + void onShowProfile() override; + void onTeleport() override; + ///*virtual*/ void onCopySLURL(); + void onRemoveSelected() override; + void updateVerbs() override; + bool isSingleItemSelected() override; + + LLToggleableMenu* getSelectionMenu() override; + LLToggleableMenu* getSortingMenu() override; + LLToggleableMenu* getCreateMenu() override; + + bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override { return false; } private: @@ -88,13 +76,15 @@ private: void onClearTeleportHistory(); bool onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response); - void refresh(); + void refresh() override; void getNextTab(const LLDate& item_date, S32& curr_tab, LLDate& tab_date); void onTeleportHistoryChange(S32 removed_index); void replaceItem(S32 removed_index); void showTeleportHistory(); void handleItemSelect(LLFlatListView* ); LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *); + static void gotSLURLCallback(const std::string& slurl); + void onGearMenuAction(const LLSD& userdata); bool isActionEnabled(const LLSD& userdata) const; void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed); @@ -115,10 +105,10 @@ private: typedef std::vector<LLAccordionCtrlTab*> item_containers_t; item_containers_t mItemContainers; - ContextMenu mContextMenu; LLContextMenu* mAccordionTabMenu; - LLHandle<LLView> mGearMenuHandle; - LLMenuButton* mMenuGearButton; + + LLToggleableMenu* mGearItemMenu; + LLToggleableMenu* mSortingMenu; boost::signals2::connection mTeleportHistoryChangedConnection; }; diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 109013498e..0723a78704 100644 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -31,6 +31,7 @@ #include "llagent.h" #include "llagentui.h" #include "llclipboard.h" +#include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "lllandmarkactions.h" #include "lllocationinputctrl.h" @@ -456,7 +457,7 @@ void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item) if(landmark == NULL) { - LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); + LLFloaterReg::showInstance("add_landmark"); } else { diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 48151c17ea..6dfe40c29a 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -164,8 +164,12 @@ void LLSidepanelAppearance::onOpen(const LLSD& key) std::string type = key["type"].asString(); if (type == "my_outfits") { - showOutfitsInventoryPanel(); + showOutfitsInventoryPanel("outfitslist_tab"); } + else if (type == "now_wearing") + { + showOutfitsInventoryPanel("cof_tab"); + } else if (type == "edit_outfit") { showOutfitEditPanel(); @@ -287,7 +291,14 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel() { toggleWearableEditPanel(FALSE); toggleOutfitEditPanel(FALSE); - toggleMyOutfitsPanel(TRUE); + toggleMyOutfitsPanel(TRUE, ""); +} + +void LLSidepanelAppearance::showOutfitsInventoryPanel(const std::string &tab_name) +{ + toggleWearableEditPanel(FALSE); + toggleOutfitEditPanel(FALSE); + toggleMyOutfitsPanel(TRUE, tab_name); } void LLSidepanelAppearance::showOutfitEditPanel() @@ -312,37 +323,42 @@ void LLSidepanelAppearance::showOutfitEditPanel() return; } - toggleMyOutfitsPanel(FALSE); + toggleMyOutfitsPanel(FALSE, ""); toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode toggleOutfitEditPanel(TRUE); } void LLSidepanelAppearance::showWearableEditPanel(LLViewerWearable *wearable /* = NULL*/, BOOL disable_camera_switch) { - toggleMyOutfitsPanel(FALSE); + toggleMyOutfitsPanel(FALSE, ""); toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode toggleWearableEditPanel(TRUE, wearable, disable_camera_switch); } -void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible) +void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible, const std::string& tab_name) { - if (!mPanelOutfitsInventory || mPanelOutfitsInventory->getVisible() == visible) - { - // visibility isn't changing, hence nothing to do - return; - } - - mPanelOutfitsInventory->setVisible(visible); - - // *TODO: Move these controls to panel_outfits_inventory.xml - // so that we don't need to toggle them explicitly. - mFilterEditor->setVisible(visible); - mCurrOutfitPanel->setVisible(visible); - - if (visible) - { - mPanelOutfitsInventory->onOpen(LLSD()); - } + if (!mPanelOutfitsInventory + || (mPanelOutfitsInventory->getVisible() == visible && tab_name.empty())) + { + // visibility isn't changing, hence nothing to do + return; + } + + mPanelOutfitsInventory->setVisible(visible); + + // *TODO: Move these controls to panel_outfits_inventory.xml + // so that we don't need to toggle them explicitly. + mFilterEditor->setVisible(visible); + mCurrOutfitPanel->setVisible(visible); + + if (visible) + { + mPanelOutfitsInventory->onOpen(LLSD()); + if (!tab_name.empty()) + { + mPanelOutfitsInventory->openApearanceTab(tab_name); + } + } } void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch) diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 7817fd317c..bb9709a2b8 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -56,7 +56,8 @@ public: void fetchInventory(); void inventoryFetched(); - void showOutfitsInventoryPanel(); + void showOutfitsInventoryPanel(); // last selected + void showOutfitsInventoryPanel(const std::string& tab_name); void showOutfitEditPanel(); void showWearableEditPanel(LLViewerWearable *wearable = NULL, BOOL disable_camera_switch = FALSE); void setWearablesLoading(bool val); @@ -72,7 +73,7 @@ private: void onOpenOutfitButtonClicked(); void onEditAppearanceButtonClicked(); - void toggleMyOutfitsPanel(BOOL visible); + void toggleMyOutfitsPanel(BOOL visible, const std::string& tab_name); void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE); void toggleWearableEditPanel(BOOL visible, LLViewerWearable* wearable = NULL, BOOL disable_camera_switch = FALSE); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 3fb79e4739..c5d5be3509 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -128,10 +128,12 @@ #include "llpanelpick.h" #include "llpanelgrouplandmoney.h" #include "llpanelgroupnotices.h" +#include "llparcel.h" #include "llpreview.h" #include "llpreviewscript.h" #include "llproxy.h" #include "llproductinforequest.h" +#include "llqueryflags.h" #include "llselectmgr.h" #include "llsky.h" #include "llstatview.h" @@ -142,6 +144,7 @@ #include "lltoolmgr.h" #include "lltrans.h" #include "llui.h" +#include "lluiusage.h" #include "llurldispatcher.h" #include "llurlentry.h" #include "llslurl.h" @@ -229,7 +232,6 @@ extern S32 gStartImageHeight; static bool gGotUseCircuitCodeAck = false; static std::string sInitialOutfit; static std::string sInitialOutfitGender; // "male" or "female" -static boost::signals2::connection sWearablesLoadedCon; static bool gUseCircuitCallbackCalled = false; @@ -1670,8 +1672,20 @@ bool idle_startup() if (STATE_INVENTORY_SEND == LLStartUp::getStartupState()) { display_startup(); + + // request mute list + LL_INFOS() << "Requesting Mute List" << LL_ENDL; + LLMuteList::getInstance()->requestFromServer(gAgent.getID()); + + // Get L$ and ownership credit information + LL_INFOS() << "Requesting Money Balance" << LL_ENDL; + LLStatusBar::sendMoneyBalanceRequest(); + + display_startup(); + // Inform simulator of our language preference LLAgentLanguage::update(); + display_startup(); // unpack thin inventory LLSD response = LLLoginInstance::getInstance()->getResponse(); @@ -1838,14 +1852,6 @@ bool idle_startup() LLLandmark::registerCallbacks(msg); display_startup(); - // request mute list - LL_INFOS() << "Requesting Mute List" << LL_ENDL; - LLMuteList::getInstance()->requestFromServer(gAgent.getID()); - display_startup(); - // Get L$ and ownership credit information - LL_INFOS() << "Requesting Money Balance" << LL_ENDL; - LLStatusBar::sendMoneyBalanceRequest(); - display_startup(); // request all group information LL_INFOS() << "Requesting Agent Data" << LL_ENDL; gAgent.sendAgentDataUpdateRequest(); @@ -1902,10 +1908,6 @@ bool idle_startup() // Set the show start location to true, now that the user has logged // on with this install. gSavedSettings.setBOOL("ShowStartLocation", TRUE); - - // Open Conversation floater on first login. - LLFloaterReg::toggleInstanceOrBringToFront("im_container"); - } display_startup(); @@ -2263,6 +2265,16 @@ bool idle_startup() gAgentAvatarp->sendHoverHeight(); + // look for parcels we own + send_places_query(LLUUID::null, + LLUUID::null, + "", + DFQ_AGENT_OWNED, + LLParcel::C_ANY, + ""); + + LLUIUsage::instance().clear(); + return TRUE; } @@ -2698,11 +2710,6 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, } else { - // FIXME SH-3860 - this creates a race condition, where COF - // changes (base outfit link added) after appearance update - // request has been submitted. - sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit); - bool do_copy = true; bool do_append = false; LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); @@ -2716,23 +2723,6 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, gAgentWearables.sendDummyAgentWearablesUpdate(); } -//static -void LLStartUp::saveInitialOutfit() -{ - if (sInitialOutfit.empty()) { - LL_DEBUGS() << "sInitialOutfit is empty" << LL_ENDL; - return; - } - - if (sWearablesLoadedCon.connected()) - { - LL_DEBUGS("Avatar") << "sWearablesLoadedCon is connected, disconnecting" << LL_ENDL; - sWearablesLoadedCon.disconnect(); - } - LL_DEBUGS("Avatar") << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << LL_ENDL; - LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false); -} - std::string& LLStartUp::getInitialOutfitName() { return sInitialOutfit; diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 3ec3ff4133..116aeb36a7 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -110,9 +110,6 @@ public: static void loadInitialOutfit( const std::string& outfit_folder_name, const std::string& gender_name ); - //save loaded initial outfit into My Outfits category - static void saveInitialOutfit(); - static std::string& getInitialOutfitName(); static std::string getUserId(); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 4d55448d78..0a87b14e17 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -416,7 +416,20 @@ void LLStatusBar::sendMoneyBalanceRequest() msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_MoneyData); msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); - gAgent.sendReliableMessage(); + + if (gDisconnected) + { + LL_DEBUGS() << "Trying to send message when disconnected, skipping balance request!" << LL_ENDL; + return; + } + if (!gAgent.getRegion()) + { + LL_DEBUGS() << "LLAgent::sendReliableMessage No region for agent yet, skipping balance request!" << LL_ENDL; + return; + } + // Double amount of retries due to this request initially happening during busy stage + // Ideally this should be turned into a capability + gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL); } diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index 8a5704939a..93fa457bd0 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -33,6 +33,8 @@ #include "lldir.h" #include "llteleporthistory.h" #include "llagent.h" +#include "llfloaterreg.h" +#include "llfloaterworldmap.h" // Max offset for two global positions to consider them as equal const F64 MAX_GLOBAL_POS_OFFSET = 5.0f; @@ -253,3 +255,23 @@ void LLTeleportHistoryStorage::goToItem(S32 idx) gAgent.teleportViaLocation(mItems[idx].mGlobalPos); } +void LLTeleportHistoryStorage::showItemOnMap(S32 idx) +{ + // Validate specified index. + if (idx < 0 || idx >= (S32)mItems.size()) + { + LL_WARNS() << "Invalid teleport history index (" << idx << ") specified" << LL_ENDL; + dump(); + return; + } + + LLVector3d landmark_global_pos = mItems[idx].mGlobalPos; + + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if (!landmark_global_pos.isExactlyZero() && worldmap_instance) + { + worldmap_instance->trackLocation(landmark_global_pos); + LLFloaterReg::showInstance("world_map", "center"); + } +} + diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h index 946ac0af1a..3578923fd7 100644 --- a/indra/newview/llteleporthistorystorage.h +++ b/indra/newview/llteleporthistorystorage.h @@ -107,6 +107,13 @@ public: */ void goToItem(S32 idx); + /** + * Show specific item on map. + * + * The item is specified by its index (starting from 0). + */ + void showItemOnMap(S32 idx); + private: void load(); diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 6a29be4aa1..8baad30e8f 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -121,6 +121,11 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal data.mURLExternal = mNotification->getURLOpenExternally(); } + if((*it).has("width")) + { + data.mWidth = (*it)["width"].asInteger(); + } + mButtonData.push_back(data); option_index++; } @@ -159,15 +164,29 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal // Calc total width of buttons S32 button_width = 0; S32 sp = font->getWidth(std::string("OO")); + S32 btn_total_width = 0; + S32 default_size_btns = 0; for( S32 i = 0; i < num_options; i++ ) - { + { S32 w = S32(font->getWidth( options[i].second ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD; - button_width = llmax( w, button_width ); + if (mButtonData[i].mWidth > w) + { + btn_total_width += mButtonData[i].mWidth; + } + else + { + button_width = llmax(w, button_width); + default_size_btns++; + } } - S32 btn_total_width = button_width; + if( num_options > 1 ) { - btn_total_width = (num_options * button_width) + ((num_options - 1) * BTN_HPAD); + btn_total_width = btn_total_width + (button_width * default_size_btns) + ((num_options - 1) * BTN_HPAD); + } + else + { + btn_total_width = llmax(btn_total_width, button_width); } // Message: create text box using raw string, as text has been structure deliberately @@ -272,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mLineEditor->setText(edit_text_contents); std::string notif_name = mNotification->getName(); - if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name)) + if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name)) { mLineEditor->setPrevalidate(&LLTextValidate::validateASCII); } @@ -333,7 +352,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal if(btn) { btn->setName(options[i].first); - btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT )); + btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, (mButtonData[i].mWidth == 0) ? button_width : mButtonData[i].mWidth, BTN_HEIGHT )); btn->setLabel(options[i].second); btn->setFont(font); @@ -348,7 +367,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal btn->setFocus(TRUE); } } - button_left += button_width + BTN_HPAD; + button_left += ((mButtonData[i].mWidth == 0) ? button_width : mButtonData[i].mWidth) + BTN_HPAD; } setCheckBoxes(HPAD, VPAD); diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h index 9b4e054bf1..bd34e40642 100644 --- a/indra/newview/lltoastalertpanel.h +++ b/indra/newview/lltoastalertpanel.h @@ -82,9 +82,14 @@ private: struct ButtonData { + ButtonData() + : mWidth(0) + {} + LLButton* mButton; std::string mURL; U32 mURLExternal; + S32 mWidth; }; std::vector<ButtonData> mButtonData; diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index bccf88128d..024f25bc98 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -387,9 +387,9 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) if (mIsScriptDialog) { // we are using default width for script buttons so we can determinate button_rows - //to get a number of rows we divide the required width of the buttons to button_panel_width - S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width); - //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width; + // to get a number of rows we divide the required width of the buttons to button_panel_width + // buttons.size() is reduced by -2 due to presence of ignore button which is calculated independently a bit lower + S32 button_rows = llceil(F32(buttons.size() - 2) * (BUTTON_WIDTH + h_pad) / (button_panel_width + h_pad)); //reserve one row for the ignore_btn button_rows++; //calculate required panel height for scripdialog notification. diff --git a/indra/newview/llurlfloaterdispatchhandler.cpp b/indra/newview/llurlfloaterdispatchhandler.cpp new file mode 100644 index 0000000000..6b1a373beb --- /dev/null +++ b/indra/newview/llurlfloaterdispatchhandler.cpp @@ -0,0 +1,214 @@ +/** + * @file llurlfloaterdispatchhandler.cpp + * @brief Handles URLFloater generic message from server + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llurlfloaterdispatchhandler.h" + +#include "llfloaterreg.h" +#include "llfloaterhowto.h" +#include "llfloaterwebcontent.h" +#include "llsdserialize.h" +#include "llviewercontrol.h" +#include "llviewergenericmessage.h" +#include "llweb.h" + +// Example: +// llOpenFloater("guidebook", "http://page.com", []); + +// values specified by server side's dispatcher +// for llopenfloater +const std::string MESSAGE_URL_FLOATER("URLFloater"); +const std::string KEY_ACTION("action"); // "action" will be the string constant "OpenURL" +const std::string VALUE_OPEN_URL("OpenURL"); +const std::string KEY_DATA("action_data"); +const std::string KEY_FLOATER("floater_title"); // name of the floater, not title +const std::string KEY_URL("floater_url"); +const std::string KEY_PARAMS("floater_params"); + +// Supported floaters +const std::string FLOATER_GUIDEBOOK("guidebook"); +const std::string FLOATER_HOW_TO("how_to"); // alias for guidebook +const std::string FLOATER_WEB_CONTENT("web_content"); + +// All arguments are palceholders! Server side will need to add validation first. +// Web content universal argument +const std::string KEY_TRUSTED_CONTENT("trusted_content"); + +// Guidebook specific arguments +const std::string KEY_WIDTH("width"); +const std::string KEY_HEGHT("height"); +const std::string KEY_CAN_CLOSE("can_close"); +const std::string KEY_TITLE("title"); + +// web_content specific arguments +const std::string KEY_SHOW_PAGE_TITLE("show_page_title"); +const std::string KEY_ALLOW_ADRESS_ENTRY("allow_address_entry"); // It is not recomended to set this to true if trusted content is allowed + + +LLUrlFloaterDispatchHandler LLUrlFloaterDispatchHandler::sUrlDispatchhandler; + +LLUrlFloaterDispatchHandler::LLUrlFloaterDispatchHandler() +{ +} + +LLUrlFloaterDispatchHandler::~LLUrlFloaterDispatchHandler() +{ +} + +void LLUrlFloaterDispatchHandler::registerInDispatcher() +{ + if (!gGenericDispatcher.isHandlerPresent(MESSAGE_URL_FLOATER)) + { + gGenericDispatcher.addHandler(MESSAGE_URL_FLOATER, &sUrlDispatchhandler); + } +} + +//virtual +bool LLUrlFloaterDispatchHandler::operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings) +{ + // invoice - transaction id + + LLSD message; + sparam_t::const_iterator it = strings.begin(); + + if (it != strings.end()) + { + const std::string& llsdRaw = *it++; + std::istringstream llsdData(llsdRaw); + if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length())) + { + LL_WARNS("URLFloater") << "Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; + return false; + } + } + + // At the moment command_params is a placeholder and code treats it as map + // Once server side adds argument validation this will be either a map or an array + std::string floater; + LLSD command_params; + std::string url; + + if (message.has(KEY_ACTION) && message[KEY_ACTION].asString() == VALUE_OPEN_URL) + { + LLSD &action_data = message[KEY_DATA]; + if (action_data.isMap()) + { + floater = action_data[KEY_FLOATER].asString(); + command_params = action_data[KEY_PARAMS]; + url = action_data[KEY_URL].asString(); + } + } + else if (message.has(KEY_FLOATER)) + { + floater = message[KEY_FLOATER].asString(); + command_params = message[KEY_PARAMS]; + url = message[KEY_URL].asString(); + } + else + { + LL_WARNS("URLFloater") << "Received " << MESSAGE_URL_FLOATER << " with unexpected data format: " << message << LL_ENDL; + return false; + } + + if (url.find("://") == std::string::npos) + { + // try unescaping + url = LLURI::unescape(url); + } + + LLFloaterWebContent::Params params; + params.url = url; + + if (floater == FLOATER_GUIDEBOOK || floater == FLOATER_HOW_TO) + { + LL_DEBUGS("URLFloater") << "Opening how_to floater with parameters: " << message << LL_ENDL; + if (command_params.isMap()) // by default is undefines + { + params.trusted_content = command_params.has(KEY_TRUSTED_CONTENT) ? command_params[KEY_TRUSTED_CONTENT].asBoolean() : false; + + // Script's side argument list can't include other lists, neither + // there is a LLRect type, so expect just width and height + if (command_params.has(KEY_WIDTH) && command_params.has(KEY_HEGHT)) + { + LLRect rect(0, command_params[KEY_HEGHT].asInteger(), command_params[KEY_WIDTH].asInteger(), 0); + params.preferred_media_size.setValue(rect); + } + } + + // Some locations will have customized guidebook, which this function easists for + // only one instance of guidebook can exist at a time, so if this command arrives, + // we need to close previous guidebook then reopen it. + + LLFloater* instance = LLFloaterReg::findInstance("guidebook"); + if (instance) + { + instance->closeHostedFloater(); + } + + LLFloaterReg::toggleInstanceOrBringToFront("guidebook", params); + + if (command_params.isMap()) + { + LLFloater* instance = LLFloaterReg::findInstance("guidebook"); + if (command_params.has(KEY_CAN_CLOSE)) + { + instance->setCanClose(command_params[KEY_CAN_CLOSE].asBoolean()); + } + if (command_params.has(KEY_TITLE)) + { + instance->setTitle(command_params[KEY_TITLE].asString()); + } + } + } + else if (floater == FLOATER_WEB_CONTENT) + { + LL_DEBUGS("URLFloater") << "Opening web_content floater with parameters: " << message << LL_ENDL; + if (command_params.isMap()) // by default is undefines, might be better idea to init params from command_params + { + params.trusted_content = command_params.has(KEY_TRUSTED_CONTENT) ? command_params[KEY_TRUSTED_CONTENT].asBoolean() : false; + params.show_page_title = command_params.has(KEY_SHOW_PAGE_TITLE) ? command_params[KEY_SHOW_PAGE_TITLE].asBoolean() : true; + params.allow_address_entry = command_params.has(KEY_ALLOW_ADRESS_ENTRY) ? command_params[KEY_ALLOW_ADRESS_ENTRY].asBoolean() : true; + } + LLFloaterReg::showInstance("web_content", params); + } + else + { + LL_DEBUGS("URLFloater") << "Unknow floater with parameters: " << message << LL_ENDL; + if (LLFloaterReg::isRegistered(floater)) + { + // A valid floater + LL_INFOS("URLFloater") << "Floater " << floater << " is not supported by llopenfloater or URLFloater" << LL_ENDL; + } + else + { + // A valid message, but no such flaoter + LL_WARNS("URLFloater") << "Recieved a command to open unknown floater: " << floater << LL_ENDL; + } + } + + return true; +} diff --git a/indra/newview/llurlfloaterdispatchhandler.h b/indra/newview/llurlfloaterdispatchhandler.h new file mode 100644 index 0000000000..1dff52c66f --- /dev/null +++ b/indra/newview/llurlfloaterdispatchhandler.h @@ -0,0 +1,49 @@ +/** + * @file llurlfloaterdispatchhandler.h + * @brief Handles URLFloater generic message from server + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLURLFLOATERDISPATCHHANDLER_H +#define LL_LLURLFLOATERDISPATCHHANDLER_H + +#include "lldispatcher.h" + +class LLUrlFloaterDispatchHandler : public LLDispatchHandler +{ +public: + LOG_CLASS(LLUrlFloaterDispatchHandler); + + LLUrlFloaterDispatchHandler(); + virtual ~LLUrlFloaterDispatchHandler(); + + virtual bool operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override; + + static void registerInDispatcher(); + +private: + static LLUrlFloaterDispatchHandler sUrlDispatchhandler; +}; + +#endif // LL_LLURLFLOATERDISPATCHHANDLER_H + diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6d939fbe21..066c874eb8 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -474,6 +474,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); + gAgent.sheduleTeleportIM(); gTextureList.mForceResetTextureStats = TRUE; gAgentCamera.resetView(TRUE, TRUE); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 414ae1fad6..5a05f89758 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -34,6 +34,7 @@ #include "llcompilequeue.h" #include "llfasttimerview.h" #include "llfloaterabout.h" +#include "llfloateraddpaymentmethod.h" #include "llfloaterauction.h" #include "llfloaterautoreplacesettings.h" #include "llfloateravatar.h" @@ -57,6 +58,7 @@ #include "llfloaterchatvoicevolume.h" #include "llfloaterconversationlog.h" #include "llfloaterconversationpreview.h" +#include "llfloatercreatelandmark.h" #include "llfloaterdeleteprefpreset.h" #include "llfloaterdestinations.h" #include "llfloatereditextdaycycle.h" @@ -74,6 +76,7 @@ #include "llfloatergroups.h" #include "llfloaterhelpbrowser.h" #include "llfloaterhoverheight.h" +#include "llfloaterhowto.h" #include "llfloaterhud.h" #include "llfloaterimagepreview.h" #include "llfloaterimsession.h" @@ -194,6 +197,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterAboutUtil::registerFloater(); LLFloaterReg::add("block_timers", "floater_fast_timers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFastTimerView>); LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>); + LLFloaterReg::add("add_payment_method", "floater_add_payment_method.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAddPaymentMethod>); LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>); LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>); @@ -220,6 +224,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater); LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>); LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>); + LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>); LLFloaterReg::add("delete_pref_preset", "floater_delete_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeletePrefPreset>); LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>); @@ -358,7 +363,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); - LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); + LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>); LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9d05f59b09..fbf057603e 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -64,6 +64,7 @@ #include "llfloaterimcontainer.h" #include "llfloaterland.h" #include "llfloaterimnearbychat.h" +#include "llfloaterlandholdings.h" #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindinglinksets.h" #include "llfloaterpay.h" @@ -185,11 +186,15 @@ const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents" LLMenuGL* gAttachSubMenu = NULL; LLMenuGL* gDetachSubMenu = NULL; LLMenuGL* gTakeOffClothes = NULL; +LLMenuGL* gDetachAvatarMenu = NULL; +LLMenuGL* gDetachHUDAvatarMenu = NULL; LLContextMenu* gAttachScreenPieMenu = NULL; LLContextMenu* gAttachPieMenu = NULL; LLContextMenu* gAttachBodyPartPieMenus[9]; LLContextMenu* gDetachPieMenu = NULL; LLContextMenu* gDetachScreenPieMenu = NULL; +LLContextMenu* gDetachAttSelfMenu = NULL; +LLContextMenu* gDetachHUDAttSelfMenu = NULL; LLContextMenu* gDetachBodyPartPieMenus[9]; // @@ -444,6 +449,9 @@ void init_menus() gMenuAttachmentOther = LLUICtrlFactory::createFromFile<LLContextMenu>( "menu_attachment_other.xml", gMenuHolder, registry); + gDetachHUDAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self HUD", true); + gDetachAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self", true); + gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>( "menu_land.xml", gMenuHolder, registry); @@ -500,6 +508,9 @@ void init_menus() gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE); gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE); + gDetachAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach", true); + gDetachHUDAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach HUD", true); + // Don't display the Memory console menu if the feature is turned off LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", TRUE); if (memoryMenu) @@ -676,19 +687,6 @@ class LLAdvancedCheckHUDInfo : public view_listener_t }; -////////////// -// FLYING // -////////////// - -class LLAdvancedAgentFlyingInfo : public view_listener_t -{ - bool handleEvent(const LLSD&) - { - return gAgent.getFlying(); - } -}; - - /////////////////////// // CLEAR GROUP CACHE // /////////////////////// @@ -3743,6 +3741,35 @@ bool enable_sitdown_self() return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying(); } +class LLSelfToggleSitStand : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + if (isAgentAvatarValid()) + { + if (gAgentAvatarp->isSitting()) + { + gAgent.standUp(); + } + else + { + gAgent.sitDown(); + } + } + return true; + } +}; + +bool enable_sit_stand() +{ + return enable_sitdown_self() || enable_standup_self(); +} + +bool enable_fly_land() +{ + return gAgent.getFlying() || LLAgent::enableFlying(); +} + class LLCheckPanelPeopleTab : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -4944,7 +4971,7 @@ void handle_buy_or_take() { LLStringUtil::format_map_t args; args["AMOUNT"] = llformat("%d", total_price); - LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "BuyingCosts", args ), total_price ); + LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price ); } } else @@ -4973,13 +5000,6 @@ bool tools_visible_take_object() return !is_selection_buy_not_take(); } -bool enable_how_to_visible(const LLSD& param) -{ - LLFloaterWebContent::Params p; - p.target = "__help_how_to"; - return LLFloaterReg::instanceVisible("how_to", p); -} - class LLToolsEnableBuyOrTake : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -5935,6 +5955,16 @@ class LLWorldSetHomeLocation : public view_listener_t } }; +class LLWorldLindenHome : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url"); + LLWeb::loadURL(url); + return true; + } +}; + class LLWorldTeleportHome : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -6017,7 +6047,7 @@ class LLWorldCreateLandmark : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); + LLFloaterReg::showInstance("add_landmark"); return true; } @@ -6348,6 +6378,11 @@ void handle_edit_outfit() LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit")); } +void handle_now_wearing() +{ + LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "now_wearing")); +} + void handle_edit_shape() { LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape")); @@ -7704,15 +7739,7 @@ class LLToggleHowTo : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloaterWebContent::Params p; - std::string url = gSavedSettings.getString("HowToHelpURL"); - p.url = LLWeb::expandURLSubstitutions(url, LLSD()); - p.show_chrome = false; - p.target = "__help_how_to"; - p.show_page_title = false; - p.preferred_media_size = LLRect(0, 460, 335, 0); - - LLFloaterReg::toggleInstanceOrBringToFront("how_to", p); + LLFloaterReg::toggleInstanceOrBringToFront("guidebook"); return true; } }; @@ -8582,37 +8609,32 @@ class LLWorldEnvSettings : public view_listener_t if (event_name == "sunrise") { - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().updateEnvironment(); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE, LLEnvironment::TRANSITION_INSTANT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); } else if (event_name == "noon") { - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().updateEnvironment(); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY, LLEnvironment::TRANSITION_INSTANT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); } else if (event_name == "sunset") { - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().updateEnvironment(); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); } else if (event_name == "midnight") { - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().updateEnvironment(); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT, LLEnvironment::TRANSITION_INSTANT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); } else if (event_name == "region") { LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().updateEnvironment(); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); } else if (event_name == "pause_clouds") @@ -8783,6 +8805,17 @@ public: } }; +class LLUpdateMembershipLabel : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + const std::string label_str = LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText"); + gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str); + + return true; + } +}; + void handle_voice_morphing_subscribe() { LLWeb::loadURL(LLTrans::getString("voice_morphing_url")); @@ -8932,11 +8965,13 @@ void initialize_menus() view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts"); + view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel"); + enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed)); // Agent commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying)); - enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying)); + enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land)); commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2)); commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2)); commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2)); @@ -8952,6 +8987,7 @@ void initialize_menus() view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight"); view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics"); commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar)); + commit.add("NowWearing", boost::bind(&handle_now_wearing)); commit.add("EditOutfit", boost::bind(&handle_edit_outfit)); commit.add("EditShape", boost::bind(&handle_edit_shape)); commit.add("HoverHeight", boost::bind(&handle_hover_height)); @@ -8984,9 +9020,6 @@ void initialize_menus() view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb"); view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); - // Me > Movement - view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying"); - //Communicate Nearby chat view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat"); @@ -9008,6 +9041,7 @@ void initialize_menus() view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome"); view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway"); view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb"); + view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome"); view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark"); view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation"); @@ -9062,7 +9096,6 @@ void initialize_menus() // Help menu // most items use the ShowFloater method view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo"); - enable.add("Help.HowToVisible", boost::bind(&enable_how_to_visible, _2)); // Advanced menu view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); @@ -9250,11 +9283,8 @@ void initialize_menus() view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState"); // Self context menu - view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp"); - enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self)); - view_listener_t::addMenu(new LLSelfSitDown(), "Self.SitDown"); - enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self)); - enable.add("Self.ShowSitDown", boost::bind(&show_sitdown_self)); + view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand"); + enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand)); view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments"); view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments"); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 0f63c8cf58..36b6971c81 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -188,10 +188,14 @@ extern LLContextMenu *gMenuMuteParticle; extern LLMenuGL* gAttachSubMenu; extern LLMenuGL* gDetachSubMenu; extern LLMenuGL* gTakeOffClothes; +extern LLMenuGL* gDetachAvatarMenu; +extern LLMenuGL* gDetachHUDAvatarMenu; extern LLContextMenu* gAttachScreenPieMenu; extern LLContextMenu* gDetachScreenPieMenu; +extern LLContextMenu* gDetachHUDAttSelfMenu; extern LLContextMenu* gAttachPieMenu; extern LLContextMenu* gDetachPieMenu; +extern LLContextMenu* gDetachAttSelfMenu; extern LLContextMenu* gAttachBodyPartPieMenus[9]; extern LLContextMenu* gDetachBodyPartPieMenus[9]; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 4b231c7067..15181dcd9f 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -830,10 +830,7 @@ void upload_done_callback( if(!(can_afford_transaction(expected_upload_cost))) { - LLStringUtil::format_map_t args; - args["NAME"] = data->mAssetInfo.getName(); - args["AMOUNT"] = llformat("%d", expected_upload_cost); - LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("UploadingCosts", args), expected_upload_cost ); + LLBuyCurrencyHTML::openCurrencyFloater( "", expected_upload_cost ); is_balance_sufficient = FALSE; } else if(region) @@ -967,10 +964,7 @@ void upload_new_resource( if (balance < uploadInfo->getExpectedUploadCost()) { // insufficient funds, bail on this upload - LLStringUtil::format_map_t args; - args["NAME"] = uploadInfo->getName(); - args["AMOUNT"] = llformat("%d", uploadInfo->getExpectedUploadCost()); - LLBuyCurrencyHTML::openCurrencyFloater(LLTrans::getString("UploadingCosts", args), uploadInfo->getExpectedUploadCost()); + LLBuyCurrencyHTML::openCurrencyFloater("", uploadInfo->getExpectedUploadCost()); return; } } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 458fc3b13d..39c891c9c1 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -116,7 +116,6 @@ #include "llviewerregion.h" #include "llfloaterregionrestarting.h" -#include <boost/algorithm/string/split.hpp> // #include <boost/foreach.hpp> #include "llnotificationmanager.h" // @@ -778,7 +777,6 @@ void response_group_invitation_coro(std::string url, LLUUID group_id, bool notif LL_DEBUGS("GroupInvite") << "Successfully sent response to group " << group_id << " invitation" << LL_ENDL; if (notify_and_update) { - LLNotificationsUtil::add("JoinGroupSuccess"); gAgent.sendAgentDataUpdateRequest(); LLGroupMgr::getInstance()->clearGroupData(group_id); @@ -5058,6 +5056,15 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) // notification was specified using the new mechanism, so we can just handle it here std::string notificationID; msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID); + + //SL-13824 skip notification when both joining a group and leaving a group + //remove this after server stops sending these messages + if (notificationID == "JoinGroupSuccess" || + notificationID == "GroupDepart") + { + return true; + } + if (!LLNotifications::getInstance()->templateExists(notificationID)) { return false; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index d5365e4ee8..06172e366d 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1715,9 +1715,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use // Let interesting parties know about agent parcel change. LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance(); - // Notify anything that wants to know when the agent changes parcels - gAgent.changeParcels(); - if (instance->mTeleportInProgress) { instance->mTeleportInProgress = FALSE; @@ -1733,6 +1730,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } parcel->setParcelEnvironmentVersion(parcel_environment_version); LL_DEBUGS("ENVIRONMENT") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL; + // Notify anything that wants to know when the agent changes parcels gAgent.changeParcels(); instance->mTeleportInProgress = FALSE; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 05f88b0a75..314c1a1f1e 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -63,6 +63,7 @@ #include "llsdutil.h" #include "llcorehttputil.h" #include "llvoicevivox.h" +#include "lluiusage.h" namespace LLStatViewer { @@ -577,6 +578,8 @@ void send_viewer_stats(bool include_preferences) fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets; fail["missing_updater"] = (S32) LLAppViewer::instance()->isUpdaterMissing(); + body["ui"] = LLUIUsage::instance().asLLSD(); + body["stats"]["voice"] = LLVoiceVivoxStats::getInstance()->read(); // Misc stats, two strings and two ints diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 458d8ced65..7faca2ee5b 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -465,6 +465,8 @@ BOOL LLVOAvatarSelf::buildMenus() if (gDetachBodyPartPieMenus[i]) { gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] ); + gDetachAttSelfMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]); + gDetachAvatarMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]); } else { @@ -493,12 +495,14 @@ BOOL LLVOAvatarSelf::buildMenus() LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); gDetachPieMenu->addChild(item); - + gDetachAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params)); + gDetachAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params)); break; } } } } + // add screen attachments for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); @@ -532,6 +536,8 @@ BOOL LLVOAvatarSelf::buildMenus() item_params.on_enable.parameter = iter->first; item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); gDetachScreenPieMenu->addChild(item); + gDetachHUDAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params)); + gDetachHUDAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params)); } } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index b0f57beff8..7d8aa6fbbd 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -684,6 +684,21 @@ void LLVivoxVoiceClient::voiceControlCoro() bool success = startAndConnectSession(); if (success) { + // enable/disable the automatic VAD and explicitly set the initial values of + // the VAD variables ourselves when it is off - see SL-15072 for more details + // note: we set the other parameters too even if the auto VAD is on which is ok + unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto"); + unsigned int vad_hangover = gSavedSettings.getU32("VivoxVadHangover"); + unsigned int vad_noise_floor = gSavedSettings.getU32("VivoxVadNoiseFloor"); + unsigned int vad_sensitivity = gSavedSettings.getU32("VivoxVadSensitivity"); + setupVADParams(vad_auto, vad_hangover, vad_noise_floor, vad_sensitivity); + + // watch for changes to the VAD settings via Debug Settings UI and act on them accordingly + gSavedSettings.getControl("VivoxVadAuto")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this)); + gSavedSettings.getControl("VivoxVadHangover")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this)); + gSavedSettings.getControl("VivoxVadNoiseFloor")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this)); + gSavedSettings.getControl("VivoxVadSensitivity")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this)); + if (mTuningMode) { performMicTuning(); @@ -3230,6 +3245,73 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates() } } +/** + * Because of the recurring voice cutout issues (SL-15072) we are going to try + * to disable the automatic VAD (Voice Activity Detection) and set the associated + * parameters directly. We will expose them via Debug Settings and that should + * let us iterate on a collection of values that work for us. Hopefully! + * + * From the VIVOX Docs: + * + * VadAuto: A flag indicating if the automatic VAD is enabled (1) or disabled (0) + * + * VadHangover: The time (in milliseconds) that it takes + * for the VAD to switch back to silence from speech mode after the last speech + * frame has been detected. + * + * VadNoiseFloor: A dimensionless value between 0 and + * 20000 (default 576) that controls the maximum level at which the noise floor + * may be set at by the VAD's noise tracking. Too low of a value will make noise + * tracking ineffective (A value of 0 disables noise tracking and the VAD then + * relies purely on the sensitivity property). Too high of a value will make + * long speech classifiable as noise. + * + * VadSensitivity: A dimensionless value between 0 and + * 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds + * to decreasing the sensitivity of the VAD (i.e. '0' is most sensitive, + * while 100 is 'least sensitive') + */ +void LLVivoxVoiceClient::setupVADParams(unsigned int vad_auto, + unsigned int vad_hangover, + unsigned int vad_noise_floor, + unsigned int vad_sensitivity) +{ + std::ostringstream stream; + + LL_INFOS("Voice") << "Setting the automatic VAD to " + << (vad_auto ? "True" : "False") + << " and discrete values to" + << " VadHangover = " << vad_hangover + << ", VadSensitivity = " << vad_sensitivity + << ", VadNoiseFloor = " << vad_noise_floor + << LL_ENDL; + + // Create a request to set the VAD parameters: + stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetVadProperties.1\">" + << "<VadAuto>" << vad_auto << "</VadAuto>" + << "<VadHangover>" << vad_hangover << "</VadHangover>" + << "<VadSensitivity>" << vad_sensitivity << "</VadSensitivity>" + << "<VadNoiseFloor>" << vad_noise_floor << "</VadNoiseFloor>" + << "</Request>\n\n\n"; + + if (!stream.str().empty()) + { + writeString(stream.str()); + } +} + +void LLVivoxVoiceClient::onVADSettingsChange() +{ + // pick up the VAD variables (one of which was changed) + unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto"); + unsigned int vad_hangover = gSavedSettings.getU32("VivoxVadHangover"); + unsigned int vad_noise_floor = gSavedSettings.getU32("VivoxVadNoiseFloor"); + unsigned int vad_sensitivity = gSavedSettings.getU32("VivoxVadSensitivity"); + + // build a VAD params change request and send it to SLVoice + setupVADParams(vad_auto, vad_hangover, vad_noise_floor, vad_sensitivity); +} + ///////////////////////////// // Response/Event handlers @@ -7582,6 +7664,18 @@ void LLVivoxProtocolParser::processResponse(std::string tag) { LLVivoxVoiceClient::getInstance()->accountGetTemplateFontsResponse(statusCode, statusString); } + else if (!stricmp(actionCstr, "Aux.SetVadProperties.1")) + { + // both values of statusCode (old and more recent) indicate valid requests + if (statusCode != 0 && statusCode != 200) + { + LL_WARNS("Voice") << "Aux.SetVadProperties.1 request failed: " + << "statusCode: " << statusCode + << " and " + << "statusString: " << statusString + << LL_ENDL; + } + } /* else if (!stricmp(actionCstr, "Account.ChannelGetList.1")) { diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 699c85066b..746201af04 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -473,6 +473,12 @@ protected: void muteListChanged(); ///////////////////////////// + // VAD changes + // disable auto-VAD and configure VAD parameters explicitly + void setupVADParams(unsigned int vad_auto, unsigned int vad_hangover, unsigned int vad_noise_floor, unsigned int vad_sensitivity); + void onVADSettingsChange(); + + ///////////////////////////// // Sending updates of current state void updatePosition(void); void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot); diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp index a2e519a61a..040d0deaf3 100644 --- a/indra/newview/llworldmipmap.cpp +++ b/indra/newview/llworldmipmap.cpp @@ -190,6 +190,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32 //LL_INFOS("WorldMap") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL; LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LL_INFOS("MAPURL") << "fetching map tile from " << imageurl << LL_ENDL; + img->setBoostLevel(LLGLTexture::BOOST_MAP); // Return the smart pointer diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index efe8102f83..7beb013fba 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -854,6 +854,9 @@ name="ColorSwatchBorderColor" value="0.45098 0.517647 0.607843 1"/> <color + name="ChatTeleportSeparatorColor" + reference="Black" /> + <color name="ChatTimestampColor" reference="White" /> <color @@ -963,4 +966,7 @@ <color name="OutfitGalleryItemUnselected" value="0.4 0.4 0.4 1" /> + <color + name="AddPaymentPanel" + value="0.27 0.27 0.27 1" /> </colors> diff --git a/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png b/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png Binary files differnew file mode 100644 index 0000000000..048da25c92 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png diff --git a/indra/newview/skins/default/textures/navbar/Landmarks.png b/indra/newview/skins/default/textures/navbar/Landmarks.png Binary files differnew file mode 100644 index 0000000000..2b35de913b --- /dev/null +++ b/indra/newview/skins/default/textures/navbar/Landmarks.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index a875c4e848..03878d9fe7 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -45,6 +45,10 @@ with the same filename but different name <texture name="AddItem_Off" file_name="icons/AddItem_Off.png" preload="false" /> <texture name="AddItem_Press" file_name="icons/AddItem_Press.png" preload="false" /> + <texture name="add_payment_image_center" file_name="windows/add_payment_image_center.png" preload="true" /> + <texture name="add_payment_image_left" file_name="windows/add_payment_image_left.png" preload="true" /> + <texture name="add_payment_image_right" file_name="windows/add_payment_image_right.png" preload="true" /> + <texture name="Arrow_Left_Off" file_name="navbar/Arrow_Left_Off.png" preload="true" /> <texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true" /> @@ -333,7 +337,11 @@ with the same filename but different name <texture name="Inv_Unknown" file_name="icons/Inv_UnknownObject.png" preload="false" /> <texture name="Inv_VersionFolderClosed" file_name="icons/Inv_VersionFolderClosed.png" preload="false" /> <texture name="Inv_VersionFolderOpen" file_name="icons/Inv_VersionFolderOpen.png" preload="false" /> - + + <texture name="Inv_Toolbar_SearchVisibility" file_name="icons/Inv_Toolbar_SearchVisibility.png" preload="false" /> + + <texture name="Landmarks_overlay" file_name="navbar/Landmarks.png" preload="false" /> + <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/> <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/> @@ -649,6 +657,7 @@ with the same filename but different name <texture name="TextField_Search_Off" file_name="widgets/TextField_Search_Off.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> <texture name="TextField_Disabled" file_name="widgets/TextField_Disabled.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> <texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="TextField_Search_Highlight" file_name="widgets/TextField_Search_Highlight.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> <texture name="Toast_CloseBtn" file_name="windows/Toast_CloseBtn.png" preload="true" /> diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png Binary files differnew file mode 100644 index 0000000000..e3944289c6 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_center.png b/indra/newview/skins/default/textures/windows/add_payment_image_center.png Binary files differnew file mode 100644 index 0000000000..b5459136cb --- /dev/null +++ b/indra/newview/skins/default/textures/windows/add_payment_image_center.png diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_left.png b/indra/newview/skins/default/textures/windows/add_payment_image_left.png Binary files differnew file mode 100644 index 0000000000..7fb65e724a --- /dev/null +++ b/indra/newview/skins/default/textures/windows/add_payment_image_left.png diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_right.png b/indra/newview/skins/default/textures/windows/add_payment_image_right.png Binary files differnew file mode 100644 index 0000000000..f1937b6318 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/add_payment_image_right.png diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png Binary files differindex 1fa10fde53..77904d7d12 100644 --- a/indra/newview/skins/default/textures/windows/first_login_image_left.png +++ b/indra/newview/skins/default/textures/windows/first_login_image_left.png diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png Binary files differindex d764d846b7..35ecce9c07 100644 --- a/indra/newview/skins/default/textures/windows/first_login_image_right.png +++ b/indra/newview/skins/default/textures/windows/first_login_image_right.png diff --git a/indra/newview/skins/default/xui/en/floater_add_payment_method.xml b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml new file mode 100644 index 0000000000..1f980564d4 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + height="405" + width="900" + layout="topleft" + name="floater_add_payment_method" + single_instance="true" + show_title="false" + legacy_header_height="0" + header_height="0" + background_visible="false" + can_resize="false" + can_drag_on_left="false" + can_minimize="false" + can_close="false"> + <floater.string + name="continue_url"> + https://secondlife.com/my/lindex/buy.php?associate_for_viewer=1 + </floater.string> + <panel + background_opaque="false" + bg_alpha_color="AddPaymentPanel" + border_visible="false" + background_visible="true" + label="wrapper_panel" + layout="topleft" + left="0" + name="wrapper_panel" + top="0" + height="405" + width="900" + follows="all" + translate="false"> + <text + type="string" + length="1" + follows="top|left|right" + font="SansSerifLargeBold" + text_color="White" + layout="topleft" + left="0" + height="14" + top_pad="30" + width="900" + halign="center" + name="title_txt"> + Add a payment method to buy Linden dollars and enjoy more of Second Life. + </text> + <button + follows="top|left|right" + height="24" + label="Get started" + font="SansSerifMedium" + layout="topleft" + left="320" + name="continue_btn" + image_unselected="PushButton_Login" + image_pressed="PushButton_Login_Pressed" + image_hover_unselected="PushButton_Login_Over" + label_color="White" + top_pad ="15" + width="140"/> + <button + follows="top|left|right" + height="24" + label="Later" + layout="topleft" + left_pad="9" + name="close_btn" + width="90"/> + <icon + height="195" + width="260" + image_name="add_payment_image_left" + layout="topleft" + left="30" + name="image_left" + top_pad="30" + use_draw_context_alpha="false"/> + <icon + height="195" + width="260" + image_name="add_payment_image_center" + layout="topleft" + left_pad="30" + name="image_center" + use_draw_context_alpha="false"/> + <icon + height="195" + width="260" + image_name="add_payment_image_right" + layout="topleft" + left_pad="30" + name="image_right" + use_draw_context_alpha="false"/> + <text + type="string" + length="1" + follows="top|left" + font="SansSerifMedium" + text_color="White" + height="75" + width="260" + top_pad="15" + layout="topleft" + word_wrap="true" + left="30" + name="image_left_desc"> + Create an avatar you love. Choose from millions of items in stores and the Second Life Marketplace. Your style is here. + </text> + <text + type="string" + length="1" + follows="top|left" + font="SansSerifMedium" + text_color="White" + height="75" + width="260" + layout="topleft" + word_wrap="true" + left_pad="30" + name="image_center_desc"> + Donate to your favorite performers and hosts. Your support helps them create great experiences. + </text> + <text + type="string" + length="1" + follows="top|left" + font="SansSerifMedium" + text_color="White" + height="75" + width="260" + layout="topleft" + word_wrap="true" + left_pad="30" + name="image_right_desc"> + Make the home of your dreams. With millions of items available to purchase, you can make your retreat unique. + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml index 59589e3665..f4a686bae1 100644 --- a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml +++ b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml @@ -5,14 +5,14 @@ save_rect="false" title="Personal Lighting" width="845" - height="240" + height="280" min_width="500" - min_height="235" + min_height="275" single_instance="true" can_resize="false"> <layout_stack name="outer_stack" width="845" - height="230" + height="275" follows="all" animate="false" top="0" @@ -276,19 +276,57 @@ height="150" width="150" thumb_mode="sun"/> + <text follows="left|top" + height="10" + layout="topleft" + left_delta="0" + top_pad="5" + width="200">Azimuth:</text> + <slider decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="359.99" + name="sun_azimuth" + top_pad="5" + width="130" + can_edit_text="true"/> + <text follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_pad="5" + width="200">Elevation:</text> + <slider decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="-90" + max_val="90" + name="sun_elevation" + top_pad="5" + width="130" + can_edit_text="true"/> <check_box control_name="sunbeacon" width="60" height="16" label="Show Beacon" layout="topleft" name="sunbeacon" - left_delta="55" - bottom="-20" - follows="bottom|right"/> + left_delta="-5" + top_pad="8" + follows="left|top"/> <text follows="left|top" height="10" layout="topleft" - left_pad="40" + left_pad="95" top="25" width="80">Scale:</text> <slider decimal_digits="2" @@ -385,15 +423,53 @@ height="150" width="150" thumb_mode="moon"/> + <text follows="left|top" + height="10" + layout="topleft" + left_delta="0" + top_pad="5" + width="200">Azimuth:</text> + <slider decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="359.99" + name="moon_azimuth" + top_pad="5" + width="130" + can_edit_text="true"/> + <text follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_pad="5" + width="200">Elevation:</text> + <slider decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="-90" + max_val="90" + name="moon_elevation" + top_pad="5" + width="130" + can_edit_text="true"/> <check_box control_name="moonbeacon" + follows="left|top" width="60" height="16" label="Show Beacon" layout="topleft" name="moonbeacon" - right="-50" - bottom="-20" - follows="bottom|right"/> + left_delta="0" + top_pad="8"/> </layout_panel> </layout_stack> </layout_panel> diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml index 92c5d8bcbe..3df2683ca8 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar.xml @@ -14,7 +14,7 @@ help_topic="avatar" save_rect="true" save_visibility="true" - title="CHOOSE AN AVATAR" + title="COMPLETE AVATARS" width="700"> <web_browser top="25" diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml index 061af1b67c..e8e83301be 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <floater - legacy_header_height="18" + can_minimize="false" - height="275" + height="285" layout="topleft" title="BUY L$" name="buy currency" @@ -17,277 +17,385 @@ name="info_cannot_buy"> Unable to Buy </floater.string> + <floater.string + name="estimated_zero"> + US$ 0.00 + </floater.string> <icon - height="215" + height="245" image_name="Linden_Dollar_Background" layout="topleft" left="0" name="normal_background" - top="17" + top="0" use_draw_context_alpha="false" width="350" /> - <text - type="string" - length="1" - follows="top|left|right" - font="SansSerifHuge" - layout="topleft" - left="20" - height="30" - top="25" - width="340" - name="info_need_more"> - You need more L$ - </text> - <text - type="string" - length="1" - follows="top|left" - height="16" + <layout_stack + animate="false" + name="outer_stack" + layout="topleft" + follows="all" + orientation="vertical" + left="0" + top="0" + width="350" + height="285"> + <layout_panel + auto_resize="false" + name="layout_panel_title" layout="topleft" - top="246" - left="15" - width="300" - name="contacting"> - Contacting LindeX... - </text> - <text - type="string" - length="1" - follows="top|left" - font="SansSerifHuge" + follows="all" + width="350" + height="35"> + <text + type="string" + length="1" + follows="top|left|right" + font="SansSerifLarge" + layout="topleft" + left="20" + height="30" + top="8" + width="340" + name="info_need_more"> + You need more L$ + </text> + <text + type="string" + length="1" + follows="top|left|right" + font="SansSerifLarge" + layout="topleft" + left="20" + height="30" + top="8" + width="300" + name="info_buying"> + Buy L$ + </text> + <view_border + bevel_style="none" + height="0" + layout="topleft" + left="20" + name="text_border" + top_delta="25" + width="300"/> + </layout_panel> + <layout_panel + auto_resize="false" + name="layout_panel_price" layout="topleft" - left="20" - height="30" - top="25" - width="300" - name="info_buying"> - Buy L$ - </text> - <text - type="string" - length="1" - follows="top|left" - font="SansSerifMedium" - height="16" + follows="all" + width="350" + height="18"> + <text + type="string" + length="1" + follows="top|left" + font="SansSerifMedium" + height="16" + layout="topleft" + left="20" + name="target_price_label" + top_pad="3" + width="210"> + You need + </text> + <text + type="string" + length="1" + font="SansSerifMedium" + follows="top|left" + halign="right" + height="16" + layout="topleft" + left="200" + name="target_price" + top_delta="0" + width="120"> + L$ [AMT] + </text> + </layout_panel> + <layout_panel + auto_resize="false" + name="layout_panel_balance" layout="topleft" - left="20" - name="balance_label" - top="65" - width="210"> - I have - </text> - <text - type="string" - length="1" - font="SansSerifMedium" - follows="top|left" - halign="right" - height="16" - layout="topleft" - left="200" - name="balance_amount" - top_delta="0" - width="120"> + follows="all" + width="350" + height="19"> + <text + type="string" + length="1" + follows="top|left" + font="SansSerifMedium" + height="16" + layout="topleft" + left="20" + name="balance_label" + top_pad="5" + width="210"> + You now have + </text> + <text + type="string" + length="1" + font="SansSerifMedium" + follows="top|left" + halign="right" + height="16" + layout="topleft" + left="200" + name="balance_amount" + top_delta="0" + width="120"> L$ [AMT] - </text> - <text - type="string" - length="1" - follows="top|left" - font="SansSerifMedium" - height="16" - top="95" - layout="topleft" - left="20" - name="currency_action" - width="210"> - I want to buy - </text> - <text - font="SansSerifMedium" - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - top_delta="0" - left="217" - name="currency_label" - width="15"> - L$ - </text> - <line_editor - type="string" - max_length_bytes="10" - halign="right" - font="SansSerifMedium" - select_on_focus="true" - follows="top|left" - top_delta="-7" - height="22" - label="L$" - left_pad="3" - name="currency_amt" - width="85"> - 1234 - </line_editor> - <text - type="string" - font="SansSerifMedium" - length="1" - follows="top|left" - height="16" - layout="topleft" - left="20" - top="125" - name="buying_label" - width="210"> - For the price - </text> - <text - type="string" - length="1" - font="SansSerifMedium" - text_color="EmphasisColor" - follows="top|left" - halign="right" - height="16" - top_delta="0" + </text> + </layout_panel> + <layout_panel + auto_resize="false" + name="layout_panel_required" layout="topleft" - left="150" - name="currency_est" - width="170"> - approx. [LOCALAMOUNT] - </text> - <text - type="string" - font="SansSerifSmall" - text_color="EmphasisColor" - length="1" - follows="top|left" - height="16" - layout="topleft" - top="125" - left="170" - width="150" - halign="right" - name="getting_data"> - Estimating... - </text> - <text - type="string" - font="SansSerifSmall" - top="145" - length="1" - follows="top|left" - height="16" - halign="right" - left="20" - width="300" - layout="topleft" - name="buy_action"> - [ACTION] - </text> - <text - type="string" - font="SansSerifMedium" - length="1" - follows="top|left" - height="16" - layout="topleft" - left="20" - name="total_label" - top="165" - width="210"> - My new balance will be - </text> - <text - type="string" - length="1" - font="SansSerifMedium" - follows="top|left" - top_delta="0" - height="16" - layout="topleft" - left="200" - halign="right" - name="total_amount" - width="120"> + follows="all" + width="350" + height="22"> + <text + type="string" + length="1" + follows="top|left" + font="SansSerifMedium" + font.style="BOLD" + height="16" + layout="topleft" + left="20" + name="required_label" + top_pad="6" + width="210"> + You should buy at least + </text> + <text + type="string" + length="1" + font="SansSerifMedium" + follows="top|left" + halign="right" + height="16" + layout="topleft" + left="200" + name="required_amount" + top_delta="0" + width="120"> L$ [AMT] - </text> - <text - type="string" - length="1" - text_color="LtGray_50" - follows="top|left" + </text> + </layout_panel> + <layout_panel + auto_resize="false" + name="layout_panel_action" layout="topleft" - halign="right" - top="189" - left="20" - width="300" - height="30" - name="currency_links"> - [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] - </text> - <text - type="string" - length="1" - text_color="LtGray_50" - follows="top|left" + follows="all" + width="350" + height="90"> + <view_border + bevel_style="none" + height="0" + layout="topleft" + left="20" + name="text_border_2" + top_pad="5" + width="300"/> + <text + type="string" + length="1" + follows="top|left" + font="SansSerifMedium" + height="16" + top_pad="15" + layout="topleft" + left="20" + name="currency_action" + width="210"> + Choose amount to buy + </text> + <text + font="SansSerifMedium" + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + top_delta="0" + left="247" + name="currency_label" + width="15"> + L$ + </text> + <line_editor + type="string" + max_length_bytes="10" + halign="right" + font="SansSerifMedium" + select_on_focus="true" + follows="top|left" + top_delta="-4" + height="22" + label="L$" + left_pad="3" + name="currency_amt" + width="55"> + 1234 + </line_editor> + <text + type="string" + length="1" + font="SansSerifMedium" + text_color="EmphasisColor" + follows="top|left" + halign="right" + height="16" + top_pad="4" + layout="topleft" + left="150" + name="currency_est" + width="170"> + Approx. [LOCALAMOUNT] + </text> + <text + type="string" + font="SansSerifSmall" + text_color="EmphasisColor" + length="1" + follows="top|left" + height="16" + layout="topleft" + left="170" + top_delta="0" + width="150" + halign="right" + name="getting_data"> + Estimating... + </text> + <text + type="string" + font="SansSerifMedium" + length="1" + follows="top|left" + height="16" + layout="topleft" + left="20" + name="total_label" + top_pad="10" + width="210"> + Your new balance will be + </text> + <text + type="string" + length="1" + font="SansSerifMedium" + follows="top|left" + top_delta="0" + height="16" + layout="topleft" + left="200" + halign="right" + name="total_amount" + width="120"> + L$ [AMT] + </text> + </layout_panel> + <layout_panel + auto_resize="false" + name="layout_panel_msg" layout="topleft" - halign="right" - top="202" - left="20" - width="300" - height="30" - name="exchange_rate_note"> + follows="all" + width="350" + height="50"> + <view_border + bevel_style="none" + height="0" + layout="topleft" + left="20" + name="text_border_3" + top_pad="0" + width="300"/> + <text + type="string" + length="1" + text_color="LtGray_50" + follows="top|left" + layout="topleft" + halign="right" + top_pad="3" + left="20" + width="300" + height="30" + name="currency_links"> + [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] + </text> + <text + type="string" + length="1" + text_color="LtGray_50" + follows="top|left" + layout="topleft" + halign="right" + top="19" + left="20" + width="300" + height="30" + name="exchange_rate_note"> Re-enter amount to see the latest exchange rate. - </text> - <text - type="string" - length="1" - text_color="LtGray_50" - follows="top|left" - layout="topleft" - halign="right" - top="208" - left="10" - width="310" - height="35" - name="purchase_warning_repurchase"> - Confirming this purchase only buys L$, not the object. - </text> - <text - type="string" - length="1" - text_color="LtGray_50" - follows="top|left" - layout="topleft" - halign="right" - top="213" - left="20" - width="300" - height="30" - name="purchase_warning_notenough"> - You aren't buying enough L$. Please increase the amount. - </text> - - <button - follows="bottom|left" - height="20" - label="Buy Now" - layout="topleft" - left="151" - name="buy_btn" - top="242" - width="90"/> - <button - follows="bottom|right" - height="20" - label="Cancel" + </text> + <text + type="string" + length="1" + follows="top|left" + layout="topleft" + font="SansSerifMedium" + top="10" + left="20" + width="310" + height="35" + name="purchase_warning_repurchase"> +After you receive your L$, you should try your +purchase again. + </text> + </layout_panel> + <layout_panel + auto_resize="false" + name="layout_panel_buttons" layout="topleft" - left_pad="10" - name="cancel_btn" - width="90"/> + follows="all" + width="350" + height="40"> + <text + type="string" + length="1" + follows="top|left" + height="16" + layout="topleft" + top_pad="0" + left="15" + width="300" + name="contacting"> + Contacting LindeX... + </text> + <button + follows="top|left|right" + height="20" + label="Buy L$ now" + layout="topleft" + left="151" + name="buy_btn" + bottom_delta ="8" + width="90"/> + <button + follows="top|left|right" + height="20" + label="Cancel" + layout="topleft" + left_pad="10" + name="cancel_btn" + width="90"/> + </layout_panel> + </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml new file mode 100644 index 0000000000..dcedaceaeb --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="false" + show_title="false" + can_minimize="false" + can_close="false" + header_height="10" + bg_opaque_image="Window_NoTitle_Foreground" + bg_alpha_image="Window_NoTitle_Background" + height="305" + layout="topleft" + name="create_landmark" + width="330"> + <string name="favorites_bar"> + Favorites bar + </string> + <text + follows="left|top" + height="15" + layout="topleft" + left="20" + name="title_label" + top="5" + font="SansSerifLargeBold" + value="Landmark added" + width="290" /> + <text + follows="left|top" + height="15" + layout="topleft" + left="20" + name="name_label" + top_pad="10" + value="Name" + width="290" /> + <line_editor + follows="left|top" + height="22" + layout="topleft" + max_length_bytes="63" + name="title_editor" + prevalidate_callback="ascii" + text_readonly_color="white" + top_pad="5" + width="290" /> + <text + follows="left|top" + height="15" + layout="topleft" + name="folder_label" + top_pad="10" + value="Landmark location:" + width="290" /> + <combo_box + follows="bottom|left" + height="23" + layout="topleft" + name="folder_combo" + top_pad="2" + width="290" /> + <text + follows="left|top" + layout="topleft" + top_pad="6" + left="20" + name="new_folder_textbox" + height="20" + parse_urls="true" + skip_link_underline="true" + wrap="true"> + [secondlife:/// Create new folder] + </text> + <text + follows="left|top" + height="15" + layout="topleft" + name="notes_label" + top_pad="10" + value="My notes" + width="290" /> + <text_editor + bg_readonly_color="DkGray0" + follows="all" + height="75" + layout="topleft" + max_length="127" + name="notes_editor" + spellcheck="true" + text_readonly_color="white" + text_type="ascii_with_newline" + top_pad="5" + width="290" + wrap="true" /> + <button + follows="bottom|left|right" + height="23" + label="OK" + layout="topleft" + mouse_opaque="false" + name="ok_btn" + top_pad="10" + left="19" + width="140" /> + <button + follows="bottom|left|right" + height="23" + label="Cancel" + layout="topleft" + left_pad="12" + mouse_opaque="false" + name="cancel_btn" + width="140" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml index 30e9002230..c609e3bd3a 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml @@ -616,7 +616,7 @@ follows="top|left" height="23" label="Save" - left="5" + left="200" top_pad="0" name="save_btn" width="156" /> diff --git a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml index dbf91b0834..a6e20880a9 100644 --- a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml +++ b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml @@ -89,7 +89,7 @@ follows="left|top|right|bottom" auto_resize="false" user_resize="false" - height="40" + height="29" visible="true"> <layout_stack follows="bottom|left|right" @@ -97,7 +97,7 @@ layout="topleft" mouse_opaque="false" name="button_bar_ls" - left="0" + left="212" orientation="horizontal" top="0" width="313"> diff --git a/indra/newview/skins/default/xui/en/floater_how_to.xml b/indra/newview/skins/default/xui/en/floater_how_to.xml index 8c0077a8cc..baff8e1bc0 100644 --- a/indra/newview/skins/default/xui/en/floater_how_to.xml +++ b/indra/newview/skins/default/xui/en/floater_how_to.xml @@ -1,18 +1,17 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater legacy_header_height="18" - can_resize="true" - can_minimize="true" - height="775" + can_resize="false" + can_minimize="false" + can_close="false" + height="525" layout="topleft" - min_height="360" - left="10000" - top="10" - min_width="335" name="floater_how_to" - help_topic="how_to" single_instance="true" + save_visibility="true" save_rect="true" - title="HOW TO" - width="780" + title="WELCOME ISLAND GUIDEBOOK" + width="310" + rel_x="-0.469309" + rel_y="-0.011166" filename="floater_web_content.xml"/>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 02a21764ce..7f863756eb 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1362,7 +1362,7 @@ top_pad="9" left="6" width="70" - label="Enable detailed logging" + label="Enable detailed logging (can be very slow)" name="verbose_logging"/> </panel> </tab_container> diff --git a/indra/newview/skins/default/xui/en/floater_my_appearance.xml b/indra/newview/skins/default/xui/en/floater_my_appearance.xml index fdea7a821a..35ad87ceb0 100644 --- a/indra/newview/skins/default/xui/en/floater_my_appearance.xml +++ b/indra/newview/skins/default/xui/en/floater_my_appearance.xml @@ -11,7 +11,7 @@ save_rect="true" single_instance="true" reuse_instance="true" - title="APPEARANCE" + title="AVATAR" min_height="440" min_width="333" width="333"> diff --git a/indra/newview/skins/default/xui/en/floater_my_scripts.xml b/indra/newview/skins/default/xui/en/floater_my_scripts.xml index 3b0b6723c7..ee6defce9d 100644 --- a/indra/newview/skins/default/xui/en/floater_my_scripts.xml +++ b/indra/newview/skins/default/xui/en/floater_my_scripts.xml @@ -7,7 +7,7 @@ layout="topleft" name="myscripts" save_rect="true" - title="My Scripts" + title="ATTACHMENT SCRIPTS" min_width="620" width="620"> <panel diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index 38f4b7715f..7ad692038e 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -173,16 +173,13 @@ parameter="avatar_render_settings" /> </menu_item_call> </context_menu> - <menu_item_separator - layout="topleft" name="Impostor seperator"/> - <menu_item_call enabled="false" label="Block Particle Owner" name="Mute Particle"> <menu_item_call.on_click function="Particle.Mute" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 59faf6a9f5..26b1c86c53 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -4,28 +4,7 @@ name="Attachment Pie"> <menu_item_call enabled="false" - label="Touch" - layout="topleft" - name="Attachment Object Touch"> - <menu_item_call.on_click - function="Object.Touch" /> - <menu_item_call.on_enable - function="Object.EnableTouch" - name="EnableTouch"/> - </menu_item_call> - <!--menu_item_call - label="Stand Up" - layout="topleft" - name="Stand Up"> - <menu_item_call.on_click - function="Self.StandUp" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableStandUp" /> - </menu_item_call--> - <menu_item_call - enabled="false" - label="Edit" + label="Edit item" layout="topleft" name="Edit..."> <menu_item_call.on_click @@ -35,7 +14,7 @@ </menu_item_call> <menu_item_call enabled="false" - label="Detach" + label="Detach item" layout="topleft" name="Detach"> <menu_item_call.on_click @@ -43,98 +22,278 @@ <menu_item_call.on_enable function="Attachment.EnableDetach" /> </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Sit Down" + enabled="false" + label="Touch item" layout="topleft" - name="Sit Down Here"> + name="Attachment Object Touch"> <menu_item_call.on_click - function="Self.SitDown" - parameter="" /> + function="Object.Touch" /> <menu_item_call.on_enable - function="Self.EnableSitDown" /> + function="Object.EnableTouch" + name="EnableTouch"/> </menu_item_call> + <menu_item_separator + layout="topleft" /> <menu_item_call -label="Stand Up" -layout="topleft" -name="Stand Up"> + label="Now wearing..." + name="NowWearing"> <menu_item_call.on_click - function="Self.StandUp" - parameter="" /> + function="NowWearing" /> <menu_item_call.on_enable - function="Self.EnableStandUp" /> + function="Edit.EnableCustomizeAvatar" /> </menu_item_call> <menu_item_call - label="My Appearance" + label="My Outfits..." name="Change Outfit"> <menu_item_call.on_click function="CustomizeAvatar" /> <menu_item_call.on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <menu_item_call label="Edit My Outfit" -layout="topleft" -name="Edit Outfit"> + <menu_item_call label="Hover height..." + layout="topleft" + name="Hover Height"> <menu_item_call.on_click - function="EditOutfit" /> + function="HoverHeight" /> <menu_item_call.on_enable - function="Edit.EnableCustomizeAvatar" /> + function="Edit.EnableHoverHeight" /> </menu_item_call> - <menu_item_call label="Edit My Shape" + <menu_item_call label="Shape..." layout="topleft" - name="Edit My Shape"> + name="Edit Shape"> <menu_item_call.on_click function="EditShape" /> <menu_item_call.on_enable function="Edit.EnableEditShape" /> </menu_item_call> - <menu_item_call label="Hover Height" - layout="topleft" - name="Hover Height"> - <menu_item_call.on_click - function="HoverHeight" /> - <menu_item_call.on_enable - function="Edit.EnableHoverHeight" /> + <menu_item_call label="Edit outfit parts..." + layout="topleft" + name="Edit Outfit"> + <menu_item_call.on_click + function="EditOutfit" /> + <menu_item_call.on_enable + function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <menu_item_call label="Reset Skeleton" + <context_menu + label="Take off" + layout="topleft" + name="Take Off >"> + <context_menu + label="Clothes" + layout="topleft" + name="Clothes >"> + <menu_item_call + enabled="false" + label="Shirt" layout="topleft" - name="Reset Skeleton"> - <menu_item_call.on_click - function="Avatar.ResetSkeleton" /> - </menu_item_call> - <menu_item_call label="Reset Skeleton And Animations" + name="Shirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="shirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="shirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Pants" layout="topleft" - name="Reset Skeleton And Animations"> - <menu_item_call.on_click - function="Avatar.ResetSkeletonAndAnimations" /> - </menu_item_call> - + name="Pants"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="pants" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="pants" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Skirt" + layout="topleft" + name="Skirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="skirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="skirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Shoes" + layout="topleft" + name="Shoes"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="shoes" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="shoes" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Socks" + layout="topleft" + name="Socks"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="socks" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="socks" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Jacket" + layout="topleft" + name="Jacket"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="jacket" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="jacket" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Gloves" + layout="topleft" + name="Gloves"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="gloves" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="gloves" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Undershirt" + layout="topleft" + name="Self Undershirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="undershirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="undershirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Underpants" + layout="topleft" + name="Self Underpants"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="underpants" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="underpants" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Tattoo" + layout="topleft" + name="Self Tattoo"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="tattoo" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="tattoo" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Physics" + layout="topleft" + name="Self Physics"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="physics" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="physics" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Alpha" + layout="topleft" + name="Self Alpha"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="alpha" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="alpha" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="All Clothes" + layout="topleft" + name="All Clothes"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="all" /> + </menu_item_call> + </context_menu> + <context_menu + label="HUD" + layout="topleft" + name="Detach Self HUD" /> + <context_menu + label="Detach" + layout="topleft" + name="Detach Self" /> + <menu_item_call + label="Detach All" + layout="topleft" + name="Detach All"> + <menu_item_call.on_click + function="Self.RemoveAllAttachments" + parameter="" /> + <menu_item_call.on_enable + function="Self.EnableRemoveAllAttachments" /> + </menu_item_call> + </context_menu> + <menu_item_separator/> <menu_item_call - label="My Friends" + label="Sit / stand" layout="topleft" - name="Friends..."> + name="Sit stand"> <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="friends_panel" /> + function="Self.ToggleSitStand"/> + <menu_item_call.on_enable + function="Self.EnableSitStand" /> </menu_item_call> <menu_item_call - label="My Groups" - layout="topleft" - name="Groups..."> + label="Fly / land" + name="Fly land"> <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="groups_panel" /> + function="Agent.toggleFlying" /> + <menu_item_call.on_enable + function="Agent.enableFlyLand" /> </menu_item_call> <menu_item_call - label="My Profile" - layout="topleft" - name="Profile..."> + label="Stop animations" + name="Stop Animating My Avatar"> <menu_item_call.on_click - function="ShowAgentProfile" - parameter="agent" /> + function="Tools.StopAllAnimations" /> + </menu_item_call> + <menu_item_separator/> + <menu_item_call label="Reset skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call label="Reset skeleton and animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> </menu_item_call> <menu_item_call label="Debug Textures" @@ -152,27 +311,27 @@ name="Edit Outfit"> <menu_item_call.on_visible function="Advanced.EnableAppearanceToXML"/> </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - enabled="false" - label="Drop" - layout="topleft" - name="Drop"> - <menu_item_call.on_click - function="Attachment.Drop" /> - <menu_item_call.on_enable - function="Attachment.EnableDrop" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> <menu_item_call enabled="false" label="Block Particle Owner" name="Mute Particle"> <menu_item_call.on_click function="Particle.Mute" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> + + <menu_item_separator + layout="topleft" /> + + <menu_item_call + enabled="false" + label="Drop item" + layout="topleft" + name="Drop"> + <menu_item_call.on_click + function="Attachment.Drop" /> + <menu_item_call.on_enable + function="Attachment.EnableDrop" /> + </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index f9fb847910..acbb9b860d 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -165,16 +165,13 @@ </menu_item_call> </context_menu> - <menu_item_separator - layout="topleft" name="Impostor seperator"/> - <menu_item_call enabled="false" label="Block Particle Owner" name="Mute Particle"> <menu_item_call.on_click function="Particle.Mute" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index 9e181d0b6d..500b6fffc2 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -3,209 +3,16 @@ layout="topleft" name="Self Pie"> <menu_item_call - label="Sit Down" + label="Now wearing..." layout="topleft" - name="Sit Down Here"> + name="NowWearing"> <menu_item_call.on_click - function="Self.SitDown" - parameter="" /> + function="NowWearing" /> <menu_item_call.on_enable - function="Self.EnableSitDown" /> + function="Edit.EnableCustomizeAvatar" /> </menu_item_call> <menu_item_call - label="Stand Up" - layout="topleft" - name="Stand Up"> - <menu_item_call.on_click - function="Self.StandUp" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableStandUp" /> - </menu_item_call> - <context_menu - label="Take Off" - layout="topleft" - name="Take Off >"> - <context_menu - label="Clothes" - layout="topleft" - name="Clothes >"> - <menu_item_call - enabled="false" - label="Shirt" - layout="topleft" - name="Shirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="shirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="shirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Pants" - layout="topleft" - name="Pants"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="pants" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="pants" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Skirt" - layout="topleft" - name="Skirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="skirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="skirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Shoes" - layout="topleft" - name="Shoes"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="shoes" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="shoes" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Socks" - layout="topleft" - name="Socks"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="socks" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="socks" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Jacket" - layout="topleft" - name="Jacket"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="jacket" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="jacket" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Gloves" - layout="topleft" - name="Gloves"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="gloves" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="gloves" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Undershirt" - layout="topleft" - name="Self Undershirt"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="undershirt" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="undershirt" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Underpants" - layout="topleft" - name="Self Underpants"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="underpants" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="underpants" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Tattoo" - layout="topleft" - name="Self Tattoo"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="tattoo" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="tattoo" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Physics" - layout="topleft" - name="Self Physics"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="physics" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="physics" /> - </menu_item_call> - <menu_item_call - enabled="false" - label="Alpha" - layout="topleft" - name="Self Alpha"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="alpha" /> - <menu_item_call.on_enable - function="Edit.EnableTakeOff" - parameter="alpha" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="All Clothes" - layout="topleft" - name="All Clothes"> - <menu_item_call.on_click - function="Edit.TakeOff" - parameter="all" /> - </menu_item_call> - </context_menu> - <context_menu - label="HUD" - layout="topleft" - name="Object Detach HUD" /> - <context_menu - label="Detach" - layout="topleft" - name="Object Detach" /> - <menu_item_call - label="Detach All" - layout="topleft" - name="Detach All"> - <menu_item_call.on_click - function="Self.RemoveAllAttachments" - parameter="" /> - <menu_item_call.on_enable - function="Self.EnableRemoveAllAttachments" /> - </menu_item_call> - </context_menu> - <menu_item_call - label="My Appearance" + label="My Outfits..." layout="topleft" name="Chenge Outfit"> <menu_item_call.on_click @@ -213,66 +20,250 @@ <menu_item_call.on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <menu_item_call label="Edit My Outfit" - layout="topleft" - name="Edit Outfit"> - <menu_item_call.on_click - function="EditOutfit" /> - <menu_item_call.on_enable - function="Edit.EnableCustomizeAvatar" /> + <menu_item_call label="Hover height..." + layout="topleft" + name="Hover Height"> + <menu_item_call.on_click + function="HoverHeight" /> + <menu_item_call.on_enable + function="Edit.EnableHoverHeight" /> </menu_item_call> - <menu_item_call label="Edit My Shape" + <menu_item_call label="Shape..." layout="topleft" - name="Edit My Shape"> + name="Edit Shape"> <menu_item_call.on_click function="EditShape" /> <menu_item_call.on_enable function="Edit.EnableEditShape" /> </menu_item_call> - <menu_item_call label="Hover Height" - layout="topleft" - name="Hover Height"> - <menu_item_call.on_click - function="HoverHeight" /> - <menu_item_call.on_enable - function="Edit.EnableHoverHeight" /> + <menu_item_call + label="Edit outfit parts..." + layout="topleft" + name="Edit Outfit"> + <menu_item_call.on_click + function="EditOutfit" /> + <menu_item_call.on_enable + function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <menu_item_call label="Reset Skeleton" + <context_menu + label="Take off" + layout="topleft" + name="Take Off >"> + <context_menu + label="Clothes" + layout="topleft" + name="Clothes >"> + <menu_item_call + enabled="false" + label="Shirt" + layout="topleft" + name="Shirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="shirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="shirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Pants" + layout="topleft" + name="Pants"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="pants" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="pants" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Skirt" + layout="topleft" + name="Skirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="skirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="skirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Shoes" + layout="topleft" + name="Shoes"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="shoes" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="shoes" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Socks" + layout="topleft" + name="Socks"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="socks" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="socks" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Jacket" + layout="topleft" + name="Jacket"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="jacket" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="jacket" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Gloves" + layout="topleft" + name="Gloves"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="gloves" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="gloves" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Undershirt" + layout="topleft" + name="Self Undershirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="undershirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="undershirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Underpants" + layout="topleft" + name="Self Underpants"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="underpants" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="underpants" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Tattoo" + layout="topleft" + name="Self Tattoo"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="tattoo" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="tattoo" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Physics" + layout="topleft" + name="Self Physics"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="physics" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="physics" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Alpha" + layout="topleft" + name="Self Alpha"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="alpha" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="alpha" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="All Clothes" + layout="topleft" + name="All Clothes"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="all" /> + </menu_item_call> + </context_menu> + <context_menu + label="HUD" + layout="topleft" + name="Object Detach HUD" /> + <context_menu + label="Detach" + layout="topleft" + name="Object Detach" /> + <menu_item_call + label="Detach All" + layout="topleft" + name="Detach All"> + <menu_item_call.on_click + function="Self.RemoveAllAttachments" + parameter="" /> + <menu_item_call.on_enable + function="Self.EnableRemoveAllAttachments" /> + </menu_item_call> + </context_menu> + <menu_item_separator/> + <menu_item_call + label="Sit / stand" + layout="topleft" + name="Sit stand"> + <menu_item_call.on_click + function="Self.ToggleSitStand"/> + <menu_item_call.on_enable + function="Self.EnableSitStand" /> + </menu_item_call> + <menu_item_call + label="Fly / land" + name="Fly land"> + <menu_item_call.on_click + function="Agent.toggleFlying" /> + <menu_item_call.on_enable + function="Agent.enableFlyLand" /> + </menu_item_call> + <menu_item_call + label="Stop animations" + name="Stop Animating My Avatar"> + <menu_item_call.on_click + function="Tools.StopAllAnimations" /> + </menu_item_call> + <menu_item_separator/> + <menu_item_call label="Reset skeleton" layout="topleft" name="Reset Skeleton"> <menu_item_call.on_click function="Avatar.ResetSkeleton" /> - </menu_item_call> - <menu_item_call label="Reset Skeleton And Animations" + </menu_item_call> + <menu_item_call label="Reset skeleton and animations" layout="topleft" name="Reset Skeleton And Animations"> <menu_item_call.on_click function="Avatar.ResetSkeletonAndAnimations" /> </menu_item_call> - <menu_item_call - label="My Friends" - layout="topleft" - name="Friends..."> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="friends_panel" /> - </menu_item_call> - <menu_item_call - label="My Groups" - layout="topleft" - name="Groups..."> - <menu_item_call.on_click - function="SideTray.PanelPeopleTab" - parameter="groups_panel" /> - </menu_item_call> - <menu_item_call - label="My Profile" - layout="topleft" - name="Profile..."> - <menu_item_call.on_click - function="ShowAgentProfile" - parameter="agent" /> - </menu_item_call> <menu_item_call label="Debug Textures" name="Debug..."> @@ -289,8 +280,6 @@ <menu_item_call.on_visible function="Advanced.EnableAppearanceToXML"/> </menu_item_call> - <menu_item_separator - layout="topleft" /> <menu_item_call enabled="false" label="Block Particle Owner" @@ -298,7 +287,7 @@ <menu_item_call.on_click function="Particle.Mute" /> - <menu_item_call.on_enable + <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_favorites.xml b/indra/newview/skins/default/xui/en/menu_favorites.xml index be380e11e5..0eab7c451b 100644 --- a/indra/newview/skins/default/xui/en/menu_favorites.xml +++ b/indra/newview/skins/default/xui/en/menu_favorites.xml @@ -21,12 +21,12 @@ parameter="about" /> </menu_item_call> <menu_item_call - label="Copy SLurl" + label="Move to Landmarks" layout="topleft" - name="Copy slurl"> + name="Move to Landmarks"> <menu_item_call.on_click function="Favorites.DoToSelected" - parameter="copy_slurl" /> + parameter="move_to_landmarks" /> </menu_item_call> <menu_item_call label="Show on Map" @@ -36,6 +36,25 @@ function="Favorites.DoToSelected" parameter="show_on_map" /> </menu_item_call> + <menu_item_call + label="Copy SLurl" + layout="topleft" + name="Copy slurl"> + <menu_item_call.on_click + function="Favorites.DoToSelected" + parameter="copy_slurl" /> + </menu_item_call> + <menu_item_call + label="Create Pick" + layout="topleft" + name="create_pick"> + <menu_item_call.on_click + function="Favorites.DoToSelected" + parameter="create_pick" /> + <menu_item_call.on_enable + function="Favorites.EnableSelected" + parameter="create_pick" /> + </menu_item_call> <menu_item_separator layout="topleft" /> @@ -59,10 +78,14 @@ function="Favorites.EnableSelected" parameter="can_paste" /> </menu_item_call> - - <menu_item_separator - layout="topleft" /> - + <menu_item_call + label="Rename" + layout="topleft" + name="rename"> + <menu_item_call.on_click + function="Favorites.DoToSelected" + parameter="rename" /> + </menu_item_call> <menu_item_call label="Delete" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml new file mode 100644 index 0000000000..46193f4a7a --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + bottom="806" + layout="topleft" + left="0" + mouse_opaque="false" + name="menu_search_visibility" + visible="false"> + <menu_item_check + label="Search Trash" + layout="topleft" + name="search_trash"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="toggle_search_trash" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="toggle_search_trash" /> + </menu_item_check> + <menu_item_check + label="Search Library" + layout="topleft" + name="search_library"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="toggle_search_library" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="toggle_search_library" /> + </menu_item_check> + <menu_item_separator + layout="topleft" /> + <menu_item_check + label="Include links" + layout="topleft" + name="include_links"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="include_links" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="include_links" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 07b3cc3bd8..96fac1c6e8 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -57,20 +57,13 @@ tear_off="true" name="Help"> <menu_item_call - label="How to..." + label="Guidebook" name="How To" shortcut="F1"> <menu_item_call.on_click function="Help.ToggleHowTo" parameter="" /> </menu_item_call> - <menu_item_call - label="Quickstart" - name="Quickstart"> - <menu_item_call.on_click - function="Advanced.ShowURL" - parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/> - </menu_item_call> <menu_item_separator/> <menu_item_call label="Knowledge Base" diff --git a/indra/newview/skins/default/xui/en/menu_picks.xml b/indra/newview/skins/default/xui/en/menu_picks.xml index ebb49c9004..a408e6136c 100644 --- a/indra/newview/skins/default/xui/en/menu_picks.xml +++ b/indra/newview/skins/default/xui/en/menu_picks.xml @@ -3,7 +3,17 @@ layout="topleft" name="Picks"> <menu_item_call - label="Info" + label="Teleport" + layout="topleft" + name="pick_teleport"> + <menu_item_call.on_click + function="Pick.Teleport" /> + <menu_item_call.on_enable + function="Pick.Enable" + parameter="teleport" /> + </menu_item_call> + <menu_item_call + label="View Pick" layout="topleft" name="pick_info"> <menu_item_call.on_click @@ -13,7 +23,7 @@ parameter="info" /> </menu_item_call> <menu_item_call - label="Edit" + label="Edit Pick" layout="topleft" name="pick_edit" visible="false"> @@ -24,17 +34,7 @@ parameter="edit" /> </menu_item_call> <menu_item_call - label="Teleport" - layout="topleft" - name="pick_teleport"> - <menu_item_call.on_click - function="Pick.Teleport" /> - <menu_item_call.on_enable - function="Pick.Enable" - parameter="teleport" /> - </menu_item_call> - <menu_item_call - label="Map" + label="Show on map" layout="topleft" name="pick_map"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_place_add_button.xml b/indra/newview/skins/default/xui/en/menu_place_add_button.xml index e3a39a1242..ad49f7c3a8 100644 --- a/indra/newview/skins/default/xui/en/menu_place_add_button.xml +++ b/indra/newview/skins/default/xui/en/menu_place_add_button.xml @@ -1,27 +1,30 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu +<toggleable_menu layout="topleft" left="0" mouse_opaque="false" - name="menu_folder_gear" + name="menu_create" visible="false"> <menu_item_call - label="Add Folder" + label="Landmark current location" layout="topleft" - name="add_folder"> + name="add_landmark"> <on_click function="Places.LandmarksGear.Add.Action" - parameter="category" /> + parameter="add_landmark_root" /> <on_enable function="Places.LandmarksGear.Enable" - parameter="category" /> + parameter="add_landmark_root" /> </menu_item_call> <menu_item_call - label="Add Landmark" + label="Create folder" layout="topleft" - name="add_landmark"> + name="add_folder"> <on_click function="Places.LandmarksGear.Add.Action" - parameter="add_landmark" /> + parameter="category_root" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="category_root" /> </menu_item_call> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml index 1aeb166e01..e9ada52a8f 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml @@ -7,15 +7,18 @@ name="menu_folder_gear" visible="false"> <menu_item_call - label="Add Landmark" + label="Landmark current location" layout="topleft" name="add_landmark"> <on_click function="Places.LandmarksGear.Add.Action" parameter="add_landmark" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="add_landmark" /> </menu_item_call> <menu_item_call - label="Add Folder" + label="Create subfolder" layout="topleft" name="add_folder"> <on_click @@ -24,6 +27,9 @@ <on_enable function="Places.LandmarksGear.Enable" parameter="category" /> + <on_visible + function="Places.LandmarksGear.Enable" + parameter="category" /> </menu_item_call> <menu_item_call label="Restore Item" @@ -120,37 +126,4 @@ function="Places.LandmarksGear.Enable" parameter="collapse" /> </menu_item_call> - <menu_item_call - label="Expand all folders" - layout="topleft" - name="expand_all"> - <on_click - function="Places.LandmarksGear.Folding.Action" - parameter="expand_all" /> - <on_enable - function="Places.LandmarksGear.Enable" - parameter="expand_all" /> - </menu_item_call> - <menu_item_call - label="Collapse all folders" - layout="topleft" - name="collapse_all"> - <on_click - function="Places.LandmarksGear.Folding.Action" - parameter="collapse_all" /> - <on_enable - function="Places.LandmarksGear.Enable" - parameter="collapse_all" /> - </menu_item_call> - <menu_item_check - label="Sort by Date" - layout="topleft" - name="sort_by_date"> - <on_check - function="Places.LandmarksGear.Check" - parameter="sort_by_date" /> - <on_click - function="Places.LandmarksGear.Folding.Action" - parameter="sort_by_date" /> - </menu_item_check> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml index ff5fdd3795..c89b498ddf 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml @@ -18,7 +18,18 @@ parameter="teleport" /> </menu_item_call> <menu_item_call - label="More Information" + label="Share" + layout="topleft" + name="share"> + <on_click + function="Places.LandmarksGear.Custom.Action" + parameter="share" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="share" /> + </menu_item_call> + <menu_item_call + label="View/Edit Landmark" layout="topleft" name="more_info"> <on_click @@ -29,6 +40,28 @@ parameter="more_info" /> </menu_item_call> <menu_item_call + label="Move to Landmarks" + layout="topleft" + name="Move to Landmarks"> + <menu_item_call.on_click + function="Places.LandmarksGear.Custom.Action" + parameter="move_to_landmarks" /> + <menu_item_call.on_visible + function="Places.LandmarksGear.Enable" + parameter="move_to_landmarks" /> + </menu_item_call> + <menu_item_call + label="Move to Favorites" + layout="topleft" + name="Move to Favorites"> + <menu_item_call.on_click + function="Places.LandmarksGear.Custom.Action" + parameter="move_to_favorites" /> + <menu_item_call.on_visible + function="Places.LandmarksGear.Enable" + parameter="move_to_favorites" /> + </menu_item_call> + <menu_item_call label="Show on Map" layout="topleft" name="show_on_map"> @@ -39,26 +72,27 @@ function="Places.LandmarksGear.Enable" parameter="show_on_map" /> </menu_item_call> - <menu_item_separator - layout="topleft" /> <menu_item_call - label="Add Landmark" + label="Copy SLurl" layout="topleft" - name="add_landmark"> + name="copy_slurl"> <on_click - function="Places.LandmarksGear.Add.Action" - parameter="add_landmark" /> - </menu_item_call> + function="Places.LandmarksGear.CopyPaste.Action" + parameter="copy_slurl" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="copy_slurl" /> + </menu_item_call> <menu_item_call - label="Add Folder" + label="Create Pick" layout="topleft" - name="add_folder"> + name="create_pick"> <on_click - function="Places.LandmarksGear.Add.Action" - parameter="category" /> + function="Places.LandmarksGear.Custom.Action" + parameter="create_pick" /> <on_enable function="Places.LandmarksGear.Enable" - parameter="category" /> + parameter="create_pick" /> </menu_item_call> <menu_item_call label="Restore Item" @@ -82,7 +116,7 @@ parameter="cut" /> </menu_item_call> <menu_item_call - label="Copy Landmark" + label="Copy" layout="topleft" name="copy_landmark"> <on_click @@ -90,17 +124,6 @@ parameter="copy" /> </menu_item_call> <menu_item_call - label="Copy SLurl" - layout="topleft" - name="copy_slurl"> - <on_click - function="Places.LandmarksGear.CopyPaste.Action" - parameter="copy_slurl" /> - <on_enable - function="Places.LandmarksGear.Enable" - parameter="copy_slurl" /> - </menu_item_call> - <menu_item_call label="Paste" layout="topleft" name="paste"> @@ -133,53 +156,4 @@ function="Places.LandmarksGear.Enable" parameter="delete" /> </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Expand all folders" - layout="topleft" - name="expand_all"> - <on_click - function="Places.LandmarksGear.Folding.Action" - parameter="expand_all" /> - <on_enable - function="Places.LandmarksGear.Enable" - parameter="expand_all" /> - </menu_item_call> - <menu_item_call - label="Collapse all folders" - layout="topleft" - name="collapse_all"> - <on_click - function="Places.LandmarksGear.Folding.Action" - parameter="collapse_all" /> - <on_enable - function="Places.LandmarksGear.Enable" - parameter="collapse_all" /> - </menu_item_call> - <menu_item_check - label="Sort by Date" - layout="topleft" - name="sort_by_date"> - <on_check - function="Places.LandmarksGear.Check" - parameter="sort_by_date" /> - <on_click - function="Places.LandmarksGear.Folding.Action" - parameter="sort_by_date" /> - <on_enable - function="Places.LandmarksGear.Enable" - parameter="sort_by_date" /> - </menu_item_check> - <menu_item_call - label="Create Pick" - layout="topleft" - name="create_pick"> - <on_click - function="Places.LandmarksGear.Custom.Action" - parameter="create_pick" /> - <on_enable - function="Places.LandmarksGear.Enable" - parameter="create_pick" /> - </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml new file mode 100644 index 0000000000..4193a72e2e --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + left="0" + mouse_opaque="false" + name="menu_sorter_gear" + visible="false"> + <menu_item_call + label="Expand all folders" + layout="topleft" + name="expand_all"> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="expand_all" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="expand_all" /> + </menu_item_call> + <menu_item_call + label="Collapse all folders" + layout="topleft" + name="collapse_all"> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="collapse_all" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="collapse_all" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_check + label="Sort by Date" + layout="topleft" + name="sort_by_date"> + <on_check + function="Places.LandmarksGear.Check" + parameter="sort_by_date" /> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="sort_by_date" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="sort_by_date" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml index bc7d4fe33b..c11d668698 100644 --- a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml @@ -12,7 +12,8 @@ label="Expand all folders" name="Expand all folders"> <menu_item_call.on_click - function="TeleportHistory.ExpandAllFolders" /> + function="TeleportHistory.GearMenu.Action" + parameter="expand_all" /> <on_enable function="TeleportHistory.GearMenu.Enable" parameter="expand_all" /> @@ -21,16 +22,10 @@ label="Collapse all folders" name="Collapse all folders"> <menu_item_call.on_click - function="TeleportHistory.CollapseAllFolders" /> + function="TeleportHistory.GearMenu.Action" + parameter="collapse_all" /> <on_enable function="TeleportHistory.GearMenu.Enable" parameter="collapse_all" /> </menu_item_call> - <menu_item_separator layout="topleft" /> - <menu_item_call - label="Clear Teleport History" - name="Clear Teleport History"> - <menu_item_call.on_click - function="TeleportHistory.ClearTeleportHistory" /> - </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml index f939c3996d..153e5a70a9 100644 --- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml +++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml @@ -1,26 +1,52 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<context_menu +<toggleable_menu + name="Teleport History Item Menu" layout="topleft" - name="Teleport History Item Context Menu"> + left="0" + mouse_opaque="false" + visible="false"> <menu_item_call label="Teleport" layout="topleft" name="Teleport"> - <menu_item_call.on_click - function="TeleportHistory.Teleport" /> + <on_click + function="TeleportHistory.GearMenu.Action" + parameter="teleport" /> + <on_enable + function="TeleportHistory.GearMenu.Enable" + parameter="teleport" /> </menu_item_call> <menu_item_call - label="More Information" + label="View" layout="topleft" name="More Information"> - <menu_item_call.on_click - function="TeleportHistory.MoreInformation" /> + <on_click + function="TeleportHistory.GearMenu.Action" + parameter="view" /> + <on_enable + function="TeleportHistory.GearMenu.Enable" + parameter="view" /> + </menu_item_call> + <menu_item_call + label="Show on map" + layout="topleft" + name="show_on_map"> + <on_click + function="TeleportHistory.GearMenu.Action" + parameter="show_on_map" /> + <on_enable + function="TeleportHistory.GearMenu.Enable" + parameter="show_on_map" /> </menu_item_call> <menu_item_call label="Copy SLurl" layout="topleft" name="CopyToClipboard"> - <menu_item_call.on_click - function="TeleportHistory.CopyToClipboard" /> + <on_click + function="TeleportHistory.GearMenu.Action" + parameter="copy_slurl" /> + <on_enable + function="TeleportHistory.GearMenu.Enable" + parameter="copy_slurl" /> </menu_item_call> -</context_menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 0a50ff089f..c550f69d26 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -15,24 +15,6 @@ function="ShowAgentProfile" parameter="agent" /> </menu_item_call> - <menu_item_call - label="Appearance..." - name="ChangeOutfit" - shortcut="control|O"> - <menu_item_call.on_click - function="Floater.ToggleOrBringToFront" - parameter="appearance" /> - <menu_item_call.on_enable - function="Edit.EnableCustomizeAvatar" /> - </menu_item_call> - <menu_item_call - label="Choose an avatar..." - name="Avatar Picker"> - <menu_item_call.on_click - function="Floater.ToggleOrBringToFront" - parameter="avatar" /> - </menu_item_call> - <menu_item_separator/> <menu_item_check label="Inventory..." name="Inventory" @@ -76,14 +58,6 @@ parameter="experiences"/> </menu_item_call> <menu_item_call - label="My Scripts..." - name="MyScripts"> - <menu_item_call.on_click - function="Floater.ToggleOrBringToFront" - parameter="my_scripts"/> - </menu_item_call> - <menu_item_separator/> - <menu_item_call label="Camera Controls..." name="Camera Controls" shortcut="control|K"> @@ -91,119 +65,24 @@ function="Floater.ToggleOrBringToFront" parameter="camera" /> </menu_item_call> - <menu_item_call - label="Hover Height" - name="HoverHeight" - shortcut="alt|control|H" - use_mac_ctrl="true" - visible="false"> - <menu_item_call.on_click - function="Floater.ToggleOrBringToFront" - parameter="edit_hover_height"/> - <menu_item_call.on_enable - function="Edit.EnableHoverHeight"/> - </menu_item_call> - <menu - create_jump_keys="true" - label="Movement" - name="Movement" - tear_off="true"> - <menu_item_call - label="Sit Down" - layout="topleft" - shortcut="alt|shift|S" - name="Sit Down Here"> - <menu_item_call.on_click - function="Self.SitDown"/> - <menu_item_call.on_visible - function="Self.ShowSitDown"/> - <menu_item_call.on_enable - function="Self.EnableSitDown" /> - </menu_item_call> - <menu_item_call - label="Stand Up" - layout="topleft" - shortcut="alt|shift|S" - name="Stand up"> - <menu_item_call.on_click - function="Self.StandUp"/> - <menu_item_call.on_visible - function="Self.EnableStandUp"/> - <menu_item_call.on_enable - function="Self.EnableStandUp" /> - </menu_item_call> - <menu_item_check - label="Fly" - name="Fly" - shortcut="HOME"> - <menu_item_check.on_check - function="Agent.getFlying" /> - <menu_item_check.on_click - function="Agent.toggleFlying" /> - <menu_item_check.on_enable - function="Agent.enableFlying" /> - </menu_item_check> - <menu_item_call - label="Stop flying" - name="Stop flying" - shortcut="HOME"> - <menu_item_call.on_click - function="Agent.toggleFlying" /> - <menu_item_call.on_enable - function="Agent.getFlying" /> - </menu_item_call> - <menu_item_check - label="Always Run" - name="Always Run" - shortcut="control|R"> - <menu_item_check.on_check - function="World.CheckAlwaysRun" /> - <menu_item_check.on_click - function="World.AlwaysRun" /> - </menu_item_check> - <menu_item_call - label="Stop Animating Me" - name="Stop Animating My Avatar" - allow_key_repeat="true" - shortcut="alt|shift|A"> - <menu_item_call.on_click - function="Tools.StopAllAnimations" /> - </menu_item_call> - <menu_item_check - label="Walk / run / fly..." - name="WalkRunFly"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="moveview" /> - <menu_item_check.on_click - function="Floater.ToggleOrBringToFront" - parameter="moveview" /> - </menu_item_check> - </menu> - <menu - create_jump_keys="true" - label="Status" - name="Status" - tear_off="true"> - <menu_item_check - name="Away" - label="Away"> - <menu_item_check.on_check - function="View.Status.CheckAway" /> - <menu_item_check.on_click - function="World.SetAway" /> - </menu_item_check> - <menu_item_check - name="Do Not Disturb" - label="Do Not Disturb"> - <menu_item_check.on_check - function="View.Status.CheckDoNotDisturb" /> - <menu_item_check.on_click - function="World.SetDoNotDisturb"/> - </menu_item_check> - - </menu> + <menu_item_separator/> + <menu_item_check + name="Away" + label="Away"> + <menu_item_check.on_check + function="View.Status.CheckAway" /> + <menu_item_check.on_click + function="World.SetAway" /> + </menu_item_check> + <menu_item_check + name="Do Not Disturb" + label="Do Not Disturb"> + <menu_item_check.on_check + function="View.Status.CheckDoNotDisturb" /> + <menu_item_check.on_click + function="World.SetDoNotDisturb"/> + </menu_item_check> <menu_item_separator/> @@ -228,6 +107,15 @@ name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/" /> </menu_item_call> + <menu_item_call + label="[Membership]" + name="Membership"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="https://secondlife.com/my/account/membership.php"/> + <menu_item_call.on_visible + function="Membership.UpdateLabel"/> + </menu_item_call> <menu_item_separator/> @@ -275,6 +163,334 @@ </menu> <menu create_jump_keys="true" + label="Avatar" + name="Avatar" + tear_off="true"> + <menu_item_call + label="Now wearing..." + name="NowWearing" + shortcut="control|O"> + <menu_item_call.on_click + function="NowWearing" /> + <menu_item_call.on_enable + function="Edit.EnableCustomizeAvatar" /> + </menu_item_call> + <menu_item_call + label="My outfits..." + name="ChangeOutfit"> + <menu_item_call.on_click + function="CustomizeAvatar" /> + <menu_item_call.on_enable + function="Edit.EnableCustomizeAvatar" /> + </menu_item_call> + <menu_item_call label="Hover height..." + layout="topleft" + shortcut="alt|control|H" + name="Hover Height"> + <menu_item_call.on_click + function="HoverHeight" /> + <menu_item_call.on_enable + function="Edit.EnableHoverHeight" /> + </menu_item_call> + <menu_item_call + label="Edit shape..." + layout="topleft" + name="Edit My Shape"> + <menu_item_call.on_click + function="EditShape" /> + <menu_item_call.on_enable + function="Edit.EnableEditShape" /> + </menu_item_call> + <menu_item_call + label="Edit outfit parts..." + layout="topleft" + name="Edit Outfit"> + <menu_item_call.on_click + function="EditOutfit" /> + <menu_item_call.on_enable + function="Edit.EnableCustomizeAvatar" /> + </menu_item_call> + <menu + label="Take off" + layout="topleft" + name="Take Off >"> + <menu + label="Clothes" + layout="topleft" + name="Clothes >"> + <menu_item_call + enabled="false" + label="Shirt" + layout="topleft" + name="Shirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="shirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="shirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Pants" + layout="topleft" + name="Pants"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="pants" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="pants" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Skirt" + layout="topleft" + name="Skirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="skirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="skirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Shoes" + layout="topleft" + name="Shoes"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="shoes" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="shoes" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Socks" + layout="topleft" + name="Socks"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="socks" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="socks" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Jacket" + layout="topleft" + name="Jacket"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="jacket" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="jacket" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Gloves" + layout="topleft" + name="Gloves"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="gloves" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="gloves" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Undershirt" + layout="topleft" + name="Self Undershirt"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="undershirt" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="undershirt" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Underpants" + layout="topleft" + name="Self Underpants"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="underpants" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="underpants" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Tattoo" + layout="topleft" + name="Self Tattoo"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="tattoo" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="tattoo" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Physics" + layout="topleft" + name="Self Physics"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="physics" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="physics" /> + </menu_item_call> + <menu_item_call + enabled="false" + label="Alpha" + layout="topleft" + name="Self Alpha"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="alpha" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="alpha" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="All Clothes" + layout="topleft" + name="All Clothes"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="all" /> + </menu_item_call> + </menu> + <menu + label="HUD" + layout="topleft" + name="Avatar Detach HUD" /> + <menu + label="Detach" + layout="topleft" + name="Avatar Detach" /> + <menu_item_call + label="Detach All" + layout="topleft" + name="Detach All"> + <menu_item_call.on_click + function="Self.RemoveAllAttachments" + parameter="" /> + <menu_item_call.on_enable + function="Self.EnableRemoveAllAttachments" /> + </menu_item_call> + </menu> + <menu_item_separator/> + <menu_item_call + label="Complete avatars..." + name="Avatar Picker"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="avatar" /> + </menu_item_call> + <menu_item_separator/> + + <menu_item_call + label="Sit / stand" + layout="topleft" + shortcut="alt|shift|S" + name="Sit stand"> + <menu_item_call.on_click + function="Self.ToggleSitStand"/> + <menu_item_call.on_enable + function="Self.EnableSitStand" /> + </menu_item_call> + <menu_item_call + label="Fly / land" + name="Fly land" + shortcut="HOME"> + <menu_item_call.on_click + function="Agent.toggleFlying" /> + <menu_item_call.on_enable + function="Agent.enableFlyLand" /> + </menu_item_call> + <menu_item_call + label="Stop animations" + name="Stop Animating My Avatar"> + <menu_item_call.on_click + function="Tools.StopAllAnimations" /> + </menu_item_call> + <menu_item_check + label="Walk / run / fly..." + name="WalkRunFly"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="moveview" /> + <menu_item_check.on_click + function="Floater.ToggleOrBringToFront" + parameter="moveview" /> + </menu_item_check> + <menu_item_check + label="Always run" + name="Always Run" + shortcut="control|R"> + <menu_item_check.on_check + function="World.CheckAlwaysRun" /> + <menu_item_check.on_click + function="World.AlwaysRun" /> + </menu_item_check> + <menu_item_separator/> + <menu_item_check + label="Gestures..." + name="Gestures" + shortcut="control|G"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="gestures" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="gestures" /> + </menu_item_check> + <menu_item_separator/> + <menu_item_call + label="Reset skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call + label="Reset skeleton and animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSkeletonAndAnimations" /> + </menu_item_call> + <menu_item_call + label="Attachment scripts..." + name="MyScripts"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="my_scripts"/> + </menu_item_call> + <menu_item_separator/> + <menu_item_call + label="Help with avatars..." + name="Help with avatars"> + <menu_item_call.on_click + function="Advanced.ShowURL" + parameter="https://community.secondlife.com/search/?type=cms_records3&tags=avatar&nodes=30&search_and_or=or"/> + </menu_item_call> + </menu> + <menu + create_jump_keys="true" label="Communicate" name="Communicate" tear_off="true"> @@ -540,12 +756,18 @@ parameter="region_info" /> </menu_item_call> <menu_item_call - label="My land holdings..." - name="My Land"> + label="My Linden Home..." + name="Linden Home"> + <menu_item_call.on_click + function="World.LindenHome"/> + </menu_item_call> + <menu_item_call + label="My land holdings..." + name="My Land"> <menu_item_call.on_click function="Floater.Show" parameter="land_holdings" /> - </menu_item_call> + </menu_item_call> <menu_item_call label="Buy this land" name="Buy Land"> @@ -1388,20 +1610,13 @@ function="World.EnvPreset" name="Help" tear_off="true"> <menu_item_call - label="How to..." + label="Guidebook" name="How To" shortcut="F1"> <menu_item_call.on_click function="Help.ToggleHowTo" parameter="" /> </menu_item_call> - <menu_item_call - label="Quickstart" - name="Quickstart"> - <menu_item_call.on_click - function="Advanced.ShowURL" - parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/> - </menu_item_call> <!-- <menu_item_call label="Tutorial" name="Tutorial"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index cc0dc5c3cc..4a02b576c2 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1024,18 +1024,6 @@ The group no longer has open enrollment. <notification icon="alertmodal.tga" - name="JoinGroupSuccess" - type="alertmodal"> -You have been added to the group - <tag>group_id</tag> - <tag>success</tag> - <usetemplate - name="okbutton" - yestext="OK"/> - </notification> - - <notification - icon="alertmodal.tga" name="JoinGroupInsufficientFunds" type="alertmodal"> Unable to transfer the required L$ [membership_fee] membership fee. @@ -2332,6 +2320,29 @@ You cannot create a landmark here because the owner of the land doesn't all </notification> <notification + icon="alertmodal.tga" + label="Create folder" + name="CreateLandmarkFolder" + type="alertmodal"> + <unique/> + Choose a name for the folder: + <tag>confirm</tag> + <form name="form"> + <input name="message" type="text"> + </input> + <button + default="true" + index="0" + name="OK" + text="OK"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> + + <notification icon="alertmodal.tga" name="CannotRecompileSelectObjectsNoScripts" type="alertmodal"> @@ -2443,9 +2454,8 @@ Teleport failed. icon="alertmodal.tga" name="invalid_tport" type="alertmodal"> -Problem encountered processing your teleport request. You may need to log back in before you can teleport. -If you continue to get this message, please check the [SUPPORT_SITE]. - <tag>fail</tag> +Teleport attempts are limited to 6 per minute. If you are having trouble, wait one minute and try teleporting again. If the problem persists, log out and log in again. + <tag>fail</tag> </notification> <notification icon="alertmodal.tga" @@ -3153,7 +3163,30 @@ See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries text="Cancel"/> </form> </notification> - + + <notification + icon="alertmodal.tga" + label="Rename Landmark" + name="RenameLandmark" + type="alertmodal"> + Choose a new name for [NAME] + <tag>confirm</tag> + <form name="form"> + <input name="new_name" type="text" width="300"> + [NAME] + </input> + <button + default="true" + index="0" + name="OK" + text="OK"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> + <notification icon="alertmodal.tga" name="RemoveFromFriends" @@ -4257,13 +4290,6 @@ Leave Group? yestext="OK"/> </notification> - <notification - icon="notify.tga" - name="GroupDepart" - type="notify"> -You have left the group '<nolink>[group_name]</nolink>'. - <tag>group</tag> - </notification> <notification icon="alertmodal.tga" @@ -5066,7 +5092,9 @@ Do you wish to proceed? name="RegionEntryAccessBlocked" type="alertmodal"> <tag>fail</tag> - The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. + The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here]. <usetemplate name="okbutton" yestext="OK"/> @@ -5153,7 +5181,9 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu name="TeleportEntryAccessBlocked" type="alertmodal"> <tag>fail</tag> - The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. + The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here]. <usetemplate name="okbutton" yestext="OK"/> @@ -5302,6 +5332,8 @@ You won't receive any more notifications that you're about to visit a region wit name="LandClaimAccessBlocked" type="alertmodal"> The land you're trying to claim has a maturity rating exceeding your current preferences. You can change your preferences using Me > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here]. <tag>fail</tag> <usetemplate name="okbutton" @@ -5371,6 +5403,8 @@ You won't receive any more notifications that you're about to visit a region wit name="LandBuyAccessBlocked" type="alertmodal"> The land you're trying to buy has a maturity rating exceeding your current preferences. You can change your preferences using Me > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here]. <tag>fail</tag> <usetemplate name="okbutton" @@ -7239,8 +7273,10 @@ You can only claim public land in the Region you're in. name="RegionTPAccessBlocked" type="alertmodal"> <tag>fail</tag> - The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. - <usetemplate + The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here]. + <usetemplate name="okbutton" yestext="OK"/> </notification> @@ -8682,7 +8718,7 @@ This upload will cost L$[PRICE], do you wish to continue with the upload? icon="alertmodal.tga" name="ConfirmClearTeleportHistory" type="alertmodal"> -Are you sure you want to delete your teleport history? +This will delete the entire list of places you have visited, and cannot be undone. Continue? <tag>confirm</tag> <usetemplate name="okcancelbuttons" @@ -11513,7 +11549,28 @@ Cannot create large prims that intersect other residents. Please re-try when ot name="okbutton" yestext="OK"/> </notification> - + + <notification + icon="alertmodal.tga" + name="AddPaymentMethod" + type="alertmodal"> +On the following page, choose a L$ amount +and click a place Order button. You will be +able to add a payment method at checkout. + <tag>confirm</tag> + <form name="form"> + <button + default="true" + index="0" + width="120" + name="Continue" + text="Continue"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> <notification icon="alert.tga" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index 553c112e6f..357a5559bf 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -26,7 +26,7 @@ name="back_btn" left="10" tab_stop="false" - top="2" + top="4" width="30" use_draw_context_alpha="false" /> <text @@ -39,17 +39,17 @@ left_pad="4" name="title" text_color="LtGray" - top="2" + top="4" width="250"> Edit Pick </text> <scroll_container color="DkGray2" follows="all" - height="502" + height="501" layout="topleft" left="8" - top_pad="10" + top_pad="9" name="profile_scroll" opaque="true" width="312"> diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index dc1553e6a3..85d73ece48 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -13,7 +13,7 @@ width="333"> <string name="edit_shape_title"> - Editing Shape + Shape </string> <string name="edit_skin_title"> diff --git a/indra/newview/skins/default/xui/en/panel_favorites.xml b/indra/newview/skins/default/xui/en/panel_favorites.xml new file mode 100644 index 0000000000..1e8ea34ad2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_favorites.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + name="Favorites" + layout="topleft" + left="0" + border="false" + background_visible="true" + bg_alpha_color="DkGray" + follows="all"> + <places_inventory_panel + allow_multi_select="true" + border="false" + top="1" + left="3" + bottom="0" + follows="all" + right="-3" + mouse_opaque="true" + name="favorites_list" + folder_view.use_ellipses="true" + start_folder.name="Favorites"/> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 7935d66aee..e82305ef17 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -67,7 +67,7 @@ name="back_btn" tool_tip="Back" tab_stop="false" - top="4" + top="2" width="30" use_draw_context_alpha="false" /> <text @@ -78,20 +78,20 @@ left_pad="7" name="title" text_color="LtGray" - top="3" + top="2" use_ellipses="true" value="Place Profile" width="280" /> <scroll_container color="DkGray2" follows="all" - height="532" + height="534" layout="topleft" left="9" name="place_scroll" opaque="true" - top_pad="10" - width="310"> + top_pad="9" + width="324"> <panel bg_alpha_color="DkGray2" follows="left|top|right" @@ -282,7 +282,6 @@ enabled="false" use_bg_color="true" bg_color="DkGray0" - parse_urls="false" follows="left|top|right" height="22" layout="topleft" @@ -290,8 +289,18 @@ name="title_value" text_color="white" top_pad="5" - use_ellipses="true" - width="290" /> + width="200" /> + <button + follows="top|right" + height="24" + label="Edit" + layout="topleft" + left_pad="8" + mouse_opaque="false" + name="edit_btn" + tool_tip="Edit landmark information" + top_delta="-1" + width="83" /> <line_editor follows="left|top|right" height="22" @@ -301,8 +310,8 @@ name="title_editor" prevalidate_callback="ascii" text_readonly_color="white" - top_delta="0" - width="290" /> + top_delta="1" + width="290"/> <text follows="left|top" height="15" @@ -344,17 +353,6 @@ name="folder_combo" top_pad="5" width="200" /> - <button - follows="bottom|left|right" - height="23" - label="Edit" - layout="topleft" - left="0" - mouse_opaque="false" - name="edit_btn" - tool_tip="Edit landmark information" - top_pad="-42" - width="100" /> </panel> </panel> </scroll_container> diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index 67a09949ce..10b925ec93 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -1,198 +1,23 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="Landmarks" - top="0" - height="400" layout="topleft" left="0" - width="313" help_topic="panel_landmarks" border="false" background_visible="true" bg_alpha_color="DkGray" follows="all"> - <accordion - background_visible="true" - bg_alpha_color="DkGray2" - bg_opaque_color="DkGray2" - follows="all" - height="373" - layout="topleft" - left="3" - name="landmarks_accordion" - top="0" - width="307"> - <accordion_tab - layout="topleft" - name="tab_favorites" - title="Favorites bar"> - <places_inventory_panel - allow_multi_select="true" - border="false" - bottom="0" - follows="all" - height="126" - left="0" - mouse_opaque="true" - name="favorites_list" - scroll.hide_scrollbar="true" - folder_view.use_ellipses="true" - start_folder.name="Favorites" - width="307"/> - </accordion_tab> - <accordion_tab - layout="topleft" - name="tab_landmarks" - title="My Landmarks"> - <places_inventory_panel - allow_multi_select="true" - border="false" - bottom="0" - follows="all" - height="126" - left="0" - mouse_opaque="true" - name="landmarks_list" - scroll.hide_scrollbar="true" - folder_view.use_ellipses="true" - start_folder.name="Landmarks" - width="307"/> - </accordion_tab> - <accordion_tab - layout="topleft" - name="tab_inventory" - title="My Inventory"> - <places_inventory_panel - allow_multi_select="true" - border="false" - bottom="0" - follows="all" - height="126" - left="0" - mouse_opaque="true" - name="my_inventory_list" - scroll.hide_scrollbar="true" - folder_view.use_ellipses="true" - start_folder.name="My Inventory" - width="307"/> - </accordion_tab> - <accordion_tab - layout="topleft" - name="tab_library" - title="Library"> - <places_inventory_panel - allow_multi_select="true" - border="false" - bottom="0" - follows="all" - height="126" - left="0" - mouse_opaque="true" - name="library_list" - scroll.hide_scrollbar="true" - folder_view.use_ellipses="true" - start_folder.name="LIBRARY" - width="313"/> - </accordion_tab> - </accordion> - <panel - background_visible="true" - bevel_style="none" - bottom="0" - follows="left|right|bottom" - height="27" - layout="bottomleft" - left="3" - name="bottom_panel" - width="313"> - - <layout_stack - animate="false" - border_size="0" - follows="left|right|bottom" - height="25" - layout="topleft" - orientation="horizontal" - top_pad="1" - left="0" - name="bottom_panel" - width="307"> - <layout_panel - auto_resize="false" - height="25" - layout="topleft" - name="options_gear_btn_panel" - width="32"> - <menu_button - follows="bottom|left" - tool_tip="Show additional options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="options_gear_btn" - top="0" - width="31" /> - </layout_panel> - <layout_panel - auto_resize="false" - height="25" - layout="topleft" - name="add_btn_panel" - width="32"> - <button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Middle_Over" - image_overlay="AddItem_Off" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" - layout="topleft" - left="0" - name="add_btn" - tool_tip="Add new landmark" - top="0" - width="31" /> - </layout_panel> - <layout_panel - auto_resize="true" - height="25" - layout="topleft" - name="dummy_panel" - width="212"> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Middle_Off" - layout="topleft" - left="0" - top="0" - name="dummy_icon" - width="211" /> - </layout_panel> - <layout_panel - auto_resize="false" - height="25" - layout="topleft" - name="trash_btn_panel" - width="31"> - <dnd_button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Right_Over" - image_overlay="TrashItem_Off" - image_selected="Toolbar_Right_Selected" - image_unselected="Toolbar_Right_Off" - left="0" - layout="topleft" - name="trash_btn" - tool_tip="Remove selected landmark" - top="0" - width="31"/> - </layout_panel> - </layout_stack> - </panel> + <places_inventory_panel + allow_multi_select="true" + border="false" + top="1" + follows="all" + left="3" + bottom="0" + right="-3" + mouse_opaque="true" + name="landmarks_list" + folder_view.use_ellipses="true" + start_folder.name="Landmarks"/> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index d77fbdec0a..2ff58035ed 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -32,30 +32,20 @@ left="12" name="ItemcountText" font="SansSerifMedium" - text_color="EmphasisColor" + text_color="InventoryItemLinkColor" use_ellipses="true" top_pad="0" width="300"> Items: </text> - <filter_editor - text_pad_left="10" - follows="left|top|right" + <combo_box height="23" - label="Enter search text" layout="topleft" left="10" - max_length_chars="300" - name="inventory search editor" top="18" - width="208" /> - <combo_box - height="23" - layout="topleft" - left_pad="4" name="search_type" - follows="top|right" - width="90"> + follows="top|left" + width="88"> <item label="Name" name="Name" @@ -72,7 +62,27 @@ label="UUID" name="UUID" value="search_by_UUID"/> - </combo_box> + </combo_box> + <menu_button + follows="top|left" + tool_tip="Show search visibility options" + height="23" + image_overlay="Inv_Toolbar_SearchVisibility" + layout="topleft" + left_pad="3" + name="options_visibility_btn" + width="31" /> + <filter_editor + text_pad_left="10" + follows="left|top|right" + height="23" + label="Enter search text" + layout="topleft" + left_pad="3" + max_length_chars="300" + highlight_text_field="true" + name="inventory search editor" + width="177" /> <tab_container follows="all" halign="center" 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 c7edba21f8..2dae2649a9 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -151,30 +151,43 @@ layout="topleft" auto_resize="true" user_resize="true" - min_width="185" + min_width="254" name="favorites_layout_panel" - width="320"> + width="342"> <icon follows="top|left" height="25" image_name="ChatBarHandle" layout="topleft" - left="-323" + left="-345" name="resize_handle" top="4" width="5" /> - + <button + height="23" + width="32" + layout="topleft" + mouse_opaque="true" + follows="left|top" + name="landmarks_btn" + tool_tip="My Landmarks" + top_delta="1" + left_pad="8" + scale_image="false" + image_overlay="Landmarks_overlay" + image_hover_unselected="PushButton_Over"> + </button> <favorites_bar follows="left|right|top" font="SansSerifSmall" height="20" layout="topleft" - left="0" + left_pad="0" top="4" name="favorite" image_drag_indication="Accordion_ArrowOpened_Off" tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!" - width="320"> + width="310"> <label follows="left|top" height="13" @@ -185,8 +198,8 @@ tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!" top="13" valign="bottom" - width="102"> - Favorites Bar + width="205"> + Your saved locations will appear here. </label> <!-- More button actually is a text box. --> <more_button diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index 3f7444dec3..d625f89f3b 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -81,7 +81,7 @@ name="title" text_color="LtGray" top="0" - value="Edit Outfit" + value="Edit outfit parts" use_ellipses="true" width="275" /> @@ -510,27 +510,31 @@ It is calculated as border_size + 2*UIResizeBarOverlap <button follows="bottom|left|right" height="23" - label="Save" + label="Save changes" left="1" layout="topleft" name="save_btn" top="0" width="155" /> - <button - follows="bottom|right" - height="23" - name="save_flyout_btn" - label="" - layout="topleft" - left_pad="-20" - tab_stop="false" - top="0" - image_selected="SegmentedBtn_Right_Selected_Press" - image_unselected="SegmentedBtn_Right_Off" - image_pressed="SegmentedBtn_Right_Press" - image_pressed_selected="SegmentedBtn_Right_Selected_Press" - image_overlay="Arrow_Small_Up" - width="20"/> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + mouse_opaque="false" + name="save_as_btn_lp" + auto_resize="true" + width="156"> + <button + follows="bottom|left|right" + height="23" + label="Save as..." + layout="topleft" + name="save_as_btn" + top="0" + left="1" + width="155" /> </layout_panel> <layout_panel follows="bottom|left|right" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index 6c8cc9d39a..7b898dbd7f 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -100,28 +100,33 @@ <button follows="bottom|left|right" height="23" - label="Save As" + label="Save changes" left="1" layout="topleft" name="save_btn" top="0" width="155" /> - <button - follows="bottom|right" - height="23" - name="save_flyout_btn" - label="" - layout="topleft" - left_pad="-20" - tab_stop="false" - image_selected="SegmentedBtn_Right_Selected_Press" - image_unselected="SegmentedBtn_Right_Off" - image_pressed="SegmentedBtn_Right_Press" - image_pressed_selected="SegmentedBtn_Right_Selected_Press" - image_overlay="Arrow_Small_Up" - width="20"/> - </layout_panel> - <layout_panel + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + mouse_opaque="false" + name="save_as_btn_lp" + auto_resize="true" + width="156"> + <button + follows="bottom|left|right" + height="23" + label="Save as..." + layout="topleft" + name="save_as_btn" + top="0" + left="1" + width="155" /> + </layout_panel> + <layout_panel follows="bottom|left|right" height="23" layout="bottomleft" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index c4248d9b92..50035fd0e3 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -12,7 +12,7 @@ width="333"> <string name="no_recent_people" - value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." /> + value="No recent people." /> <string name="no_filtered_recent_people" value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]." /> @@ -30,8 +30,13 @@ value="No friends" /> <string name="no_friends_msg"> - Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend. -Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map]. + To add someone as a friend, right-click on their avatar or their name. + +Looking for places with more people? + +[secondlife:///app/floater/destinations Destination Guide] has locations chosen by Second Life staff. + +[secondlife:///app/search/ Search] lets you search all of Second Life for certain keywords. </string> <string name="no_filtered_friends_msg"> @@ -45,8 +50,11 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M name="no_filtered_groups_msg" value="Didn't find what you're looking for? Try [secondlife:///app/search/groups/[SEARCH_TERM] Search]." /> <string - name="no_groups_msg" - value="Looking for Groups to join? Try [secondlife:///app/search/groups Search]." /> + name="no_groups_msg"> +You are not a member of any groups. + +Learn about [https://community.secondlife.com/knowledgebase/joining-and-participating-in-groups-r51/ groups in Second Life.] + </string> <string name="MiniMapToolTipMsg" value="[REGION](Double-click to open Map, shift-drag to pan)"/> diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index 36b7b0501b..bdde2cab20 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -172,7 +172,7 @@ name="back_btn" tool_tip="Back" tab_stop="false" - top="4" + top="2" width="30" use_draw_context_alpha="false" /> <text @@ -183,20 +183,20 @@ left_pad="10" name="title" text_color="LtGray" - top="4" + top="2" use_ellipses="true" value="Place Profile" width="280" /> <scroll_container color="DkGray2" follows="all" - height="572" + height="575" layout="topleft" left="9" name="place_scroll" opaque="true" - top_pad="10" - width="310"> + top_pad="9" + width="324"> <panel bg_alpha_color="DkGray2" follows="left|top|right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 1f32ae53ba..58be4d4c5e 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -11,30 +11,156 @@ background_visible="true" top="0" left="0" width="333"> - <string - name="landmarks_tab_title" - value="MY LANDMARKS" /> - <string - name="teleport_history_tab_title" - value="TELEPORT HISTORY" /> - <filter_editor - text_pad_left="10" - follows="left|top|right" - font="SansSerifSmall" - height="23" - layout="topleft" - left="10" - label="Filter My Places" - max_length_chars="300" - name="Filter" - tab_group="1" - top="3" - width="303" /> + <string + name="landmarks_tab_title" + value="LANDMARKS" /> + <string + name="teleport_history_tab_title" + value="VISITED" /> + <string + name="favorites_tab_title" + value="FAVORITES" /> + <string + name="tooltip_trash_items" + value="Remove selected landmark or folder" /> + <string + name="tooltip_trash_history" + value="Delete list of visited places" /> + <layout_stack + animate="false" + border_size="0" + follows="all" + height="564" + layout="topleft" + orientation="vertical" + top="1" + left="0" + name="places_layout_panel" + width="333"> + <layout_panel + auto_resize="true" + height="538" + layout="topleft" + name="main_panel" + width="333"> + <layout_stack + animate="false" + border_size="0" + follows="left|top|right" + height="27" + layout="topleft" + orientation="horizontal" + top="0" + left="0" + name="top_menu_panel" + width="320"> + <layout_panel + auto_resize="true" + layout="topleft" + name="filter_panel" + width="193"> + <filter_editor + text_pad_left="10" + follows="left|top|right" + font="SansSerifSmall" + height="23" + layout="topleft" + left="10" + label="Filter My Places" + max_length_chars="300" + name="Filter" + tab_group="1" + top="3" + width="181" /> + </layout_panel> + <layout_panel + auto_resize="false" + height="25" + layout="topleft" + name="options_gear_btn_panel" + width="32"> + <menu_button + follows="bottom|left" + tool_tip="Show options" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + menu_position="bottomleft" + layout="topleft" + left="0" + name="options_gear_btn" + top="0" + width="31" /> + </layout_panel> + <layout_panel + auto_resize="false" + height="25" + layout="topleft" + name="options_sort_btn_panel" + width="32"> + <menu_button + follows="bottom|left" + tool_tip="Show sorting options" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + menu_position="bottomleft" + layout="topleft" + left="0" + name="sorting_menu_btn" + top="0" + width="31" /> + </layout_panel> + <layout_panel + auto_resize="false" + height="25" + layout="topleft" + name="add_btn_panel" + width="32"> + <menu_button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="AddItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + menu_position="bottomleft" + layout="topleft" + left="0" + name="add_menu_btn" + tool_tip="Add new landmark or folder" + top="0" + width="31" /> + </layout_panel> + <layout_panel + auto_resize="false" + height="25" + layout="topleft" + name="trash_btn_panel" + width="31"> + <dnd_button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Right_Over" + image_overlay="TrashItem_Off" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" + left="0" + layout="topleft" + name="trash_btn" + top="0" + width="31"/> + </layout_panel> + </layout_stack> <tab_container follows="all" - halign="center" - height="503" layout="topleft" + halign="center" + height="504" left="6" name="Places Tabs" tab_min_width="80" @@ -42,40 +168,50 @@ background_visible="true" tab_height="30" tab_group="2" tab_position="top" - top_pad="10" - width="315" /> + top_pad="7" + width="318" + visible="true"/> <panel class="panel_place_profile" filename="panel_place_profile.xml" follows="all" - height="533" layout="topleft" + height="533" left="0" + top="4" help_topic="place_profile" name="panel_place_profile" - top="5" visible="false" - width="315" /> + width="318" /> <panel class="panel_landmark_info" filename="panel_landmark_info.xml" follows="all" - height="533" layout="topleft" + height="533" left="0" + top="4" help_topic="landmark" name="panel_landmark_info" - top="5" visible="false" - width="315" /> + width="318" /> + </layout_panel> + + <!--*********************** Button wrappers ***********************--> + <layout_panel + auto_resize="false" + layout="topleft" + height="25" + name="button_layout_panel"> <panel follows="bottom|left|right" height="23" layout="topleft" left="4" + top="2" name="button_panel" - width="315"> - + width="318"> + <layout_stack follows="bottom|left|right" height="23" @@ -186,41 +322,6 @@ background_visible="true" name="lp2" auto_resize="true" width="116"> - - <!--*********************** Profile button ***********************--> - - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - mouse_opaque="false" - name="bottom_bar_profile_ls" - left="0" - orientation="horizontal" - top="0" - width="110"> - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - mouse_opaque="false" - name="profile_btn_lp" - auto_resize="true" - width="102"> - <button - follows="bottom|left|right" - height="23" - label="Profile" - layout="topleft" - mouse_opaque="false" - name="profile_btn" - left="1" - tool_tip="Show place profile" - top="0" - width="101" /> - </layout_panel> - </layout_stack> <!--*********************** Close button ***********************--> @@ -265,6 +366,7 @@ background_visible="true" <layout_stack follows="bottom|left|right" + animate="false" height="23" layout="topleft" mouse_opaque="false" @@ -319,4 +421,6 @@ background_visible="true" </layout_panel> </layout_stack> </panel> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml index 0e3de821d1..1ad78dbb13 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml @@ -38,7 +38,7 @@ height="10" layout="topleft" left_delta="10" - top_delta="30" + top_delta="25" width="100"> Position: </text> @@ -93,7 +93,7 @@ follows="left|top" height="10" layout="topleft" - left_delta="-5" + left_delta="65" top_delta="20" width="80"> Color: @@ -108,12 +108,58 @@ name="sun_moon_color" top_pad="5" width="60" /> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-235" + top_delta="-3" + width="200"> + Azimuth: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="359.99" + name="sun_azimuth" + top_delta="13" + width="215" + can_edit_text="true"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="22" + width="200"> + Elevation: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="-90" + max_val="90" + name="sun_elevation" + top_delta="13" + width="215" + can_edit_text="true"/> <text follows="left|top" height="10" layout="topleft" - left_delta="-160" - top_delta="27" + left_delta="-5" + top_delta="22" width="200"> Glow Focus: </text> @@ -128,8 +174,8 @@ min_val="-2" max_val="2" name="glow_focus" - top_delta="15" - width="250" + top_delta="13" + width="215" can_edit_text="true"/> <text follows="left|top" @@ -151,8 +197,8 @@ min_val="0" max_val="1.99" name="glow_size" - top_delta="15" - width="250" + top_delta="13" + width="215" can_edit_text="true"/> <text follows="left|top" @@ -174,20 +220,20 @@ min_val="0" max_val="500" name="star_brightness" - top_delta="15" - width="250" + top_delta="13" + width="215" can_edit_text="true"/> <check_box control_name="sunbeacon" + follows="left|top" + layout="topleft" width="60" height="16" label="Show Beacon" - layout="topleft" - name="sunbeacon" - right="-50" - bottom="-10" - follows="bottom|right"/> + name="sunbeacon" + top_pad="5" + left_delta="-8"/> </layout_panel> <layout_panel @@ -227,7 +273,7 @@ height="10" layout="topleft" left_delta="10" - top_delta="30" + top_delta="25" width="100"> Position: </text> @@ -278,39 +324,85 @@ top_delta="15" width="130" can_edit_text="true"/> - <text - follows="left|top" - height="10" - layout="topleft" - left_delta="-5" - top_delta="22" - width="200"> - Brightness: - </text> - <slider - decimal_digits="2" - follows="left|top" - height="16" - increment="0.01" - initial_value="0" - layout="topleft" - left_delta="5" - min_val="0.0" - max_val="1.0" - name="moon_brightness" - top_delta="15" - width="130" - can_edit_text="true"/> - <check_box + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-170" + top_delta="32" + width="200"> + Azimuth: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="359.99" + name="moon_azimuth" + top_delta="13" + width="215" + can_edit_text="true"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="22" + width="200"> + Elevation: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="-90" + max_val="90" + name="moon_elevation" + top_delta="13" + width="215" + can_edit_text="true"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="22" + width="200"> + Brightness: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="16" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0.0" + max_val="1.0" + name="moon_brightness" + top_delta="13" + width="215" + can_edit_text="true"/> + <check_box control_name="moonbeacon" + follows="left|top" + layout="topleft" width="60" height="16" label="Show Beacon" - layout="topleft" name="moonbeacon" - right="-50" - bottom="-10" - follows="bottom|right"/> + top_pad="5" + left_delta="-8"/> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index 768efc2f3f..55c47c90a4 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -6,7 +6,7 @@ bg_alpha_color="DkGray"> <accordion follows="left|top|right|bottom" - height="373" + height="400" layout="topleft" left="3" top="0" @@ -147,37 +147,4 @@ </flat_list_view> </accordion_tab> </accordion> - <panel - background_visible="true" - bevel_style="none" - bottom="0" - follows="left|right|bottom" - height="27" - layout="bottomleft" - left="3" - name="bottom_panel" - width="313"> - <menu_button - follows="bottom|left" - tool_tip="Show additional options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="gear_btn" - top="1" - width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="dummy_icon" - width="273" - /> - </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 440e8b140f..f604a16b0b 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2296,9 +2296,9 @@ For AI Character: Get the closest navigable point to the point provided. <!-- inventory --> <string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string> - <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> - <string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string> - <string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string> + <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> + <string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string> + <string name="FavoritesNoMatchingItems">To add a place to your favorites bar, click the star to the right of the location name.</string> <string name="MarketplaceNoListing">You have no listings yet.</string> <string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string> <string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string> @@ -2418,6 +2418,7 @@ If you continue to receive this message, please contact Second Life support for <string name="Scripts" value=" Scripts," /> <string name="Sounds" value=" Sounds," /> <string name="Textures" value=" Textures," /> + <string name="Settings" value=" Settings," /> <string name="Snapshots" value=" Snapshots," /> <string name="No Filters" value="No " /> <string name="Since Logoff" value=" - Since Logoff" /> @@ -2835,7 +2836,6 @@ If you continue to receive this message, please contact Second Life support for <string name="AcquiredItems">Acquired Items</string> <string name="Cancel">Cancel</string> <string name="UploadingCosts">Uploading [NAME] costs L$ [AMOUNT]</string> - <string name="BuyingCosts">Buying this costs L$ [AMOUNT]</string> <string name="UnknownFileExtension"> Unknown file extension .%s Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim @@ -3759,6 +3759,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="unread_chat_multiple"> [SOURCES] have said something new </string> + <string name="teleport_preamble_compact_chat"> + You are now at + </string> <string name="session_initialization_timed_out_error"> The session initialization is timed out </string> @@ -3768,6 +3771,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string> <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string> + <string name="lindenhomes_get_home_url">https://secondlife.com/land/lindenhomes/member.php</string> + <string name="lindenhomes_my_home_url">https://land.secondlife.com/en-Us/lindenhomes/my-home.php</string> + <string name="membership_url">https://secondlife.com/my/account/membership.php</string> + <!-- Financial operations strings --> <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string> <string name="paid_you_ldollars_gift">[NAME] paid you L$[AMOUNT]: [REASON]</string> @@ -3791,11 +3798,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="to upload">to upload</string> <string name="to publish a classified ad">to publish a classified ad</string> - <string name="giving">Giving L$ [AMOUNT]</string> <string name="uploading_costs">Uploading costs L$ [AMOUNT]</string> <string name="this_costs">This costs L$ [AMOUNT]</string> - <string name="buying_selected_land">Buying selected land for L$ [AMOUNT]</string> - <string name="this_object_costs">This object costs L$ [AMOUNT]</string> + + <string name="buying_selected_land">This land costs</string> + <string name="this_object_costs">This item costs</string> + <string name="giving">You want to give</string> <string name="group_role_everyone">Everyone</string> <string name="group_role_officers">Officers</string> @@ -3958,6 +3966,9 @@ Please check http://status.secondlifegrid.net to see if there is a known problem <string name="Premium PlusMembership">Premium Plus</string> <string name="InternalMembership">Internal</string> <!-- No need to translate --> + <string name="MembershipUpgradeText">Upgrade to Premium</string> + <string name="MembershipPremiumText">My Premium membership</string> + <!-- Question strings for delete items notifications --> <string name="DeleteItems">Delete selected items?</string> <string name="DeleteItem">Delete selected item?</string> @@ -4114,8 +4125,8 @@ Try enclosing path to the editor with double quotes. <!-- commands --> <string name="Command_AboutLand_Label">About land</string> - <string name="Command_Appearance_Label">Appearance</string> - <string name="Command_Avatar_Label">Avatar</string> + <string name="Command_Appearance_Label">Outfits</string> + <string name="Command_Avatar_Label">Complete avatars</string> <string name="Command_Build_Label">Build</string> <string name="Command_Chat_Label">Chat</string> <string name="Command_Conversations_Label">Conversations</string> @@ -4124,7 +4135,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Environments_Label">My Environments</string> <string name="Command_Gestures_Label">Gestures</string> <string name="Command_Grid_Status_Label">Grid status</string> - <string name="Command_HowTo_Label">How to</string> + <string name="Command_HowTo_Label">Guidebook</string> <string name="Command_Inventory_Label">Inventory</string> <string name="Command_Map_Label">Map</string> <string name="Command_Marketplace_Label">Marketplace</string> diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml index 57f8bb542d..1456114b25 100644 --- a/indra/newview/skins/default/xui/en/teleport_strings.xml +++ b/indra/newview/skins/default/xui/en/teleport_strings.xml @@ -2,8 +2,7 @@ <teleport_messages> <message_set name="errors"> <message name="invalid_tport"> - Problem encountered processing your teleport request. You may need to log back in before you can teleport. -If you continue to get this message, please check the [SUPPORT_SITE]. + Teleport attempts are limited to 6 per minute. If you are having trouble, wait one minute and try teleporting again. If the problem persists, log out and log in again. </message> <message name="invalid_region_handoff"> Problem encountered processing your region crossing. You may need to log back in before you can cross regions. diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml index 2cc4abdd30..1c4822b8d5 100644 --- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml @@ -6,9 +6,11 @@ text_pad_left="7" select_on_focus="true" text_tentative_color="TextFgTentativeColor" + highlight_text_field="false" background_image="TextField_Search_Off" background_image_disabled="TextField_Search_Disabled" - background_image_focused="TextField_Search_Active"> + background_image_focused="TextField_Search_Active" + background_image_highlight="TextField_Search_Highlight"> <search_button label="" top_pad="4" left_pad="4" diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml index faa0404b35..dc5a07bf4f 100644 --- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml @@ -7,9 +7,11 @@ text_pad_right="6" select_on_focus="true" text_tentative_color="TextFgTentativeColor" + highlight_text_field="false" background_image="TextField_Search_Off" background_image_disabled="TextField_Search_Disabled" - background_image_focused="TextField_Search_Active" > + background_image_focused="TextField_Search_Active" + background_image_highlight="TextField_Search_Highlight"> <search_button top_pad="4" left_pad="4" |