diff options
Diffstat (limited to 'indra')
30 files changed, 789 insertions, 79 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 88a5c3a587..f3a99dcef2 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1522,7 +1522,7 @@ void LLTextBase::reflow() } S32 line_height = 0; - S32 seg_line_offset = line_count; + S32 seg_line_offset = line_count + 1; while(seg_iter != mSegments.end()) { diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index dbec4b5d65..7ed18801cf 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -203,6 +203,7 @@ set(viewer_SOURCE_FILES llfloaterautoreplacesettings.cpp llfloateravatar.cpp llfloateravatarpicker.cpp + llfloateravatarrendersettings.cpp llfloateravatartextures.cpp llfloaterbeacons.cpp llfloaterbigpreview.cpp @@ -820,6 +821,7 @@ set(viewer_HEADER_FILES llfloaterautoreplacesettings.h llfloateravatar.h llfloateravatarpicker.h + llfloateravatarrendersettings.h llfloateravatartextures.h llfloaterbeacons.h llfloaterbigpreview.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index fb644d3d5a..097a9ac7b9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8426,6 +8426,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>AlwaysRenderFriends</key> + <map> + <key>Comment</key> + <string>Always render friends regardless of max complexity</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderAvatar</key> <map> <key>Comment</key> diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index e335eabd1a..7723dbf978 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1537,6 +1537,11 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal() } else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR) { + LLVector3 focus_target = isAgentAvatarValid() + ? gAgentAvatarp->mHeadp->getWorldPosition() + : gAgent.getPositionAgent(); + LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target); + mFocusTargetGlobal = focus_target_global; return mFocusTargetGlobal; } else if (!mFocusOnAvatar) diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp new file mode 100644 index 0000000000..e7ac3f2737 --- /dev/null +++ b/indra/newview/llfloateravatarrendersettings.cpp @@ -0,0 +1,286 @@ +/** + * @file llfloateravatarrendersettings.cpp + * @brief Shows the list of avatars with non-default rendering settings + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2017, 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 "llfloateravatarrendersettings.h" + +#include "llavatarnamecache.h" +#include "llfloateravatarpicker.h" +#include "llfiltereditor.h" +#include "llfloaterreg.h" +#include "llnamelistctrl.h" +#include "llmenugl.h" +#include "llviewerobjectlist.h" +#include "llvoavatar.h" + +class LLSettingsContextMenu : public LLListContextMenu + +{ +public: + LLSettingsContextMenu(LLFloaterAvatarRenderSettings* floater_settings) + : mFloaterSettings(floater_settings) + {} +protected: + LLContextMenu* createMenu() + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + registrar.add("Settings.SetRendering", boost::bind(&LLFloaterAvatarRenderSettings::onCustomAction, mFloaterSettings, _2, mUUIDs.front())); + enable_registrar.add("Settings.IsSelected", boost::bind(&LLFloaterAvatarRenderSettings::isActionChecked, mFloaterSettings, _2, mUUIDs.front())); + LLContextMenu* menu = createFromFile("menu_avatar_rendering_settings.xml"); + + return menu; + } + + LLFloaterAvatarRenderSettings* mFloaterSettings; +}; + +class LLAvatarRenderMuteListObserver : public LLMuteListObserver +{ + /* virtual */ void onChange() { LLFloaterAvatarRenderSettings::setNeedsUpdate();} +}; + +static LLAvatarRenderMuteListObserver sAvatarRenderMuteListObserver; + +LLFloaterAvatarRenderSettings::LLFloaterAvatarRenderSettings(const LLSD& key) +: LLFloater(key), + mAvatarSettingsList(NULL), + mNeedsUpdate(false) +{ + mContextMenu = new LLSettingsContextMenu(this); + LLRenderMuteList::getInstance()->addObserver(&sAvatarRenderMuteListObserver); + mCommitCallbackRegistrar.add("Settings.AddNewEntry", boost::bind(&LLFloaterAvatarRenderSettings::onClickAdd, this, _2)); +} + +LLFloaterAvatarRenderSettings::~LLFloaterAvatarRenderSettings() +{ + delete mContextMenu; + LLRenderMuteList::getInstance()->removeObserver(&sAvatarRenderMuteListObserver); +} + +BOOL LLFloaterAvatarRenderSettings::postBuild() +{ + LLFloater::postBuild(); + mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list"); + mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3)); + this->setVisibleCallback(boost::bind(&LLFloaterAvatarRenderSettings::removePicker, this)); + getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2)); + + return TRUE; +} + +void LLFloaterAvatarRenderSettings::removePicker() +{ + if(mPicker.get()) + { + mPicker.get()->closeFloater(); + } +} + +void LLFloaterAvatarRenderSettings::draw() +{ + if(mNeedsUpdate) + { + updateList(); + mNeedsUpdate = false; + } + + LLFloater::draw(); +} + +void LLFloaterAvatarRenderSettings::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y) +{ + LLNameListCtrl* list = dynamic_cast<LLNameListCtrl*>(ctrl); + if (!list) return; + list->selectItemAt(x, y, MASK_NONE); + uuid_vec_t selected_uuids; + + if(list->getCurrentID().notNull()) + { + selected_uuids.push_back(list->getCurrentID()); + mContextMenu->show(ctrl, selected_uuids, x, y); + } +} + +void LLFloaterAvatarRenderSettings::onOpen(const LLSD& key) +{ + updateList(); +} + +void LLFloaterAvatarRenderSettings::updateList() +{ + mAvatarSettingsList->deleteAllItems(); + LLAvatarName av_name; + LLNameListCtrl::NameItem item_params; + for (std::map<LLUUID, S32>::iterator iter = LLRenderMuteList::getInstance()->sVisuallyMuteSettingsMap.begin(); iter != LLRenderMuteList::getInstance()->sVisuallyMuteSettingsMap.end(); iter++) + { + item_params.value = iter->first; + LLAvatarNameCache::get(iter->first, &av_name); + if(!isHiddenRow(av_name.getCompleteName())) + { + item_params.columns.add().value(av_name.getCompleteName()).column("name"); + std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render"); + item_params.columns.add().value(setting).column("setting"); + mAvatarSettingsList->addNameItemRow(item_params); + } + } +} + +void LLFloaterAvatarRenderSettings::onFilterEdit(const std::string& search_string) +{ + std::string filter_upper = search_string; + LLStringUtil::toUpper(filter_upper); + if (mNameFilter != filter_upper) + { + mNameFilter = filter_upper; + mNeedsUpdate = true; + } +} + +bool LLFloaterAvatarRenderSettings::isHiddenRow(const std::string& av_name) +{ + if (mNameFilter.empty()) return false; + std::string upper_name = av_name; + LLStringUtil::toUpper(upper_name); + return std::string::npos == upper_name.find(mNameFilter); +} + +static LLVOAvatar* find_avatar(const LLUUID& id) +{ + LLViewerObject *obj = gObjectList.findObject(id); + while (obj && obj->isAttachment()) + { + obj = (LLViewerObject *)obj->getParent(); + } + + if (obj && obj->isAvatar()) + { + return (LLVOAvatar*)obj; + } + else + { + return NULL; + } +} + + +void LLFloaterAvatarRenderSettings::onCustomAction (const LLSD& userdata, const LLUUID& av_id) +{ + const std::string command_name = userdata.asString(); + + S32 new_setting = 0; + if ("default" == command_name) + { + new_setting = S32(LLVOAvatar::AV_RENDER_NORMALLY); + } + else if ("never" == command_name) + { + new_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER); + } + else if ("always" == command_name) + { + new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER); + } + + LLVOAvatar *avatarp = find_avatar(av_id); + if (avatarp) + { + avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting)); + } + else + { + LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting); + } +} + + +bool LLFloaterAvatarRenderSettings::isActionChecked(const LLSD& userdata, const LLUUID& av_id) +{ + const std::string command_name = userdata.asString(); + + S32 visual_setting = LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(av_id); + if ("default" == command_name) + { + return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY)); + } + else if ("never" == command_name) + { + return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER)); + } + else if ("always" == command_name) + { + return (visual_setting == S32(LLVOAvatar::AV_ALWAYS_RENDER)); + } + return false; +} + +void LLFloaterAvatarRenderSettings::setNeedsUpdate() +{ + LLFloaterAvatarRenderSettings* instance = LLFloaterReg::getTypedInstance<LLFloaterAvatarRenderSettings>("avatar_render_settings"); + if(!instance) return; + instance->mNeedsUpdate = true; +} + +void LLFloaterAvatarRenderSettings::onClickAdd(const LLSD& userdata) +{ + const std::string command_name = userdata.asString(); + S32 visual_setting = 0; + if ("never" == command_name) + { + visual_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER); + } + else if ("always" == command_name) + { + visual_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER); + } + + LLView * button = findChild<LLButton>("plus_btn", TRUE); + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker * picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterAvatarRenderSettings::callbackAvatarPicked, this, _1, visual_setting), + FALSE, TRUE, FALSE, root_floater->getName(), button); + + if (root_floater) + { + root_floater->addDependentFloater(picker); + } + + mPicker = picker->getHandle(); +} + +void LLFloaterAvatarRenderSettings::callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting) +{ + if (ids.empty()) return; + + LLVOAvatar *avatarp = find_avatar(ids[0]); + if (avatarp) + { + avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(visual_setting)); + } + else + { + LLRenderMuteList::getInstance()->saveVisualMuteSetting(ids[0], visual_setting); + } +} diff --git a/indra/newview/llfloateravatarrendersettings.h b/indra/newview/llfloateravatarrendersettings.h new file mode 100644 index 0000000000..fe727bcf32 --- /dev/null +++ b/indra/newview/llfloateravatarrendersettings.h @@ -0,0 +1,71 @@ +/** + * @file llfloateravatarrendersettings.h + * @brief Shows the list of avatars with non-default rendering settings + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2017, 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_LLFLOATERAVATARRENDERSETTINGS_H +#define LL_LLFLOATERAVATARRENDERSETTINGS_H + +#include "llfloater.h" +#include "lllistcontextmenu.h" +#include "llmutelist.h" + +class LLNameListCtrl; + +class LLFloaterAvatarRenderSettings : public LLFloater +{ +public: + + LLFloaterAvatarRenderSettings(const LLSD& key); + virtual ~LLFloaterAvatarRenderSettings(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void draw(); + + void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y); + + void updateList(); + void onFilterEdit(const std::string& search_string); + void onCustomAction (const LLSD& userdata, const LLUUID& av_id); + bool isActionChecked(const LLSD& userdata, const LLUUID& av_id); + void onClickAdd(const LLSD& userdata); + + static void setNeedsUpdate(); + +private: + bool isHiddenRow(const std::string& av_name); + void callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting); + void removePicker(); + + bool mNeedsUpdate; + LLListContextMenu* mContextMenu; + LLNameListCtrl* mAvatarSettingsList; + LLHandle<LLFloater> mPicker; + + std::string mNameFilter; +}; + + +#endif //LL_LLFLOATERAVATARRENDERSETTINGS_H diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index df4bc043e5..1f460c05ec 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -360,6 +360,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this)); mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this)); mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this)); + mCommitCallbackRegistrar.add("Pref.RenderExceptions", boost::bind(&LLFloaterPreference::onClickRenderExceptions, this)); mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this)); mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this)); mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this)); @@ -385,7 +386,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2)); - + gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged, _2)); LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this ); @@ -786,10 +787,12 @@ void LLFloaterPreference::onOpen(const LLSD& key) LLButton* load_btn = findChild<LLButton>("PrefLoadButton"); LLButton* save_btn = findChild<LLButton>("PrefSaveButton"); LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton"); + LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton"); load_btn->setEnabled(started); save_btn->setEnabled(started); delete_btn->setEnabled(started); + exceptions_btn->setEnabled(started); } void LLFloaterPreference::onVertexShaderEnable() @@ -2075,6 +2078,11 @@ void LLFloaterPreference::onClickSpellChecker() LLFloaterReg::showInstance("prefs_spellchecker"); } +void LLFloaterPreference::onClickRenderExceptions() +{ + LLFloaterReg::showInstance("avatar_render_settings"); +} + void LLFloaterPreference::onClickAdvanced() { LLFloaterReg::showInstance("prefs_graphics_advanced"); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index ea199cf034..2bb2e7e9ff 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -171,6 +171,7 @@ public: void onClickPermsDefault(); void onClickAutoReplace(); void onClickSpellChecker(); + void onClickRenderExceptions(); void onClickAdvanced(); void applyUIColor(LLUICtrl* ctrl, const LLSD& param); void getUIColor(LLUICtrl* ctrl, const LLSD& param); diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 4a77edc565..a8919db828 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -360,9 +360,12 @@ void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching) } } +static LLTrace::BlockTimerStatHandle FTM_BULK_FETCH("Bulk Fetch"); + // Bundle up a bunch of requests to send all at once. void LLInventoryModelBackgroundFetch::bulkFetch() { + LL_RECORD_BLOCK_TIME(FTM_BULK_FETCH); //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was //sent. If it exceeds our retry time, go ahead and fire off another batch. diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 54f95520db..a0e19f2d19 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -121,7 +121,6 @@ namespace { { // Prompt the user with the warning (so they know why things are failing) LLSD subs; - subs["[ERROR_REASON]"] = reason; // We do show long descriptions in the alert (unlikely to be readable). The description string will be in the log though. std::string description; if (result.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT)) @@ -145,6 +144,16 @@ namespace { { description = result.asString(); } + std::string reason_lc = reason; + LLStringUtil::toLower(reason_lc); + if (!description.empty() && reason_lc.find("unknown") != std::string::npos) + { + subs["[ERROR_REASON]"] = ""; + } + else + { + subs["[ERROR_REASON]"] = "'" + reason +"'\n"; + } subs["[ERROR_DESCRIPTION]"] = description; LLNotificationsUtil::add("MerchantTransactionFailed", subs); } diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 3af9c2f912..02b28a2bf8 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -812,3 +812,99 @@ void LLMuteList::notifyObserversDetailed(const LLMute& mute) it = mObservers.upper_bound(observer); } } + +LLRenderMuteList::LLRenderMuteList() +{} + +bool LLRenderMuteList::saveToFile() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt"); + LLFILE* fp = LLFile::fopen(filename, "wb"); + if (!fp) + { + LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL; + return false; + } + for (std::map<LLUUID, S32>::iterator it = sVisuallyMuteSettingsMap.begin(); it != sVisuallyMuteSettingsMap.end(); ++it) + { + if (it->second != 0) + { + std::string id_string; + it->first.toString(id_string); + fprintf(fp, "%d %s\n", (S32)it->second, id_string.c_str()); + } + } + fclose(fp); + return true; +} + +bool LLRenderMuteList::loadFromFile() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt"); + LLFILE* fp = LLFile::fopen(filename, "rb"); + if (!fp) + { + LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL; + return false; + } + + char id_buffer[MAX_STRING]; + char buffer[MAX_STRING]; + while (!feof(fp) && fgets(buffer, MAX_STRING, fp)) + { + id_buffer[0] = '\0'; + S32 setting = 0; + sscanf(buffer, " %d %254s\n", &setting, id_buffer); + sVisuallyMuteSettingsMap[LLUUID(id_buffer)] = setting; + } + fclose(fp); + return true; +} + +void LLRenderMuteList::saveVisualMuteSetting(const LLUUID& agent_id, S32 setting) +{ + if(setting == 0) + { + sVisuallyMuteSettingsMap.erase(agent_id); + } + else + { + sVisuallyMuteSettingsMap[agent_id] = setting; + } + saveToFile(); + notifyObservers(); +} + +S32 LLRenderMuteList::getSavedVisualMuteSetting(const LLUUID& agent_id) +{ + std::map<LLUUID, S32>::iterator iter = sVisuallyMuteSettingsMap.find(agent_id); + if (iter != sVisuallyMuteSettingsMap.end()) + { + return iter->second; + } + + return 0; +} + +void LLRenderMuteList::addObserver(LLMuteListObserver* observer) +{ + mObservers.insert(observer); +} + +void LLRenderMuteList::removeObserver(LLMuteListObserver* observer) +{ + mObservers.erase(observer); +} + +void LLRenderMuteList::notifyObservers() +{ + for (observer_set_t::iterator it = mObservers.begin(); + it != mObservers.end(); + ) + { + LLMuteListObserver* observer = *it; + observer->onChange(); + // In case onChange() deleted an entry. + it = mObservers.upper_bound(observer); + } +} diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 4ceddc97fd..9ab978353b 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -175,5 +175,25 @@ public: virtual void onChangeDetailed(const LLMute& ) { } }; +class LLRenderMuteList : public LLSingleton<LLRenderMuteList> +{ + LLSINGLETON(LLRenderMuteList); +public: + bool loadFromFile(); + bool saveToFile(); + S32 getSavedVisualMuteSetting(const LLUUID& agent_id); + void saveVisualMuteSetting(const LLUUID& agent_id, S32 setting); + + void addObserver(LLMuteListObserver* observer); + void removeObserver(LLMuteListObserver* observer); + + std::map<LLUUID, S32> sVisuallyMuteSettingsMap; + +private: + void notifyObservers(); + typedef std::set<LLMuteListObserver*> observer_set_t; + observer_set_t mObservers; +}; + #endif //LL_MUTELIST_H diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp index ebf9153da9..3d18e837af 100644 --- a/indra/newview/llpanelsnapshotpostcard.cpp +++ b/indra/newview/llpanelsnapshotpostcard.cpp @@ -106,6 +106,14 @@ BOOL LLPanelSnapshotPostcard::postBuild() // virtual void LLPanelSnapshotPostcard::onOpen(const LLSD& key) { + LLUICtrl* name_form = getChild<LLUICtrl>("name_form"); + if (name_form && name_form->getValue().asString().empty()) + { + std::string name_string; + LLAgentUI::buildFullname(name_string); + getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string)); + } + LLPanelSnapshot::onOpen(key); } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 353c61da0c..983a7ca1ae 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -614,6 +614,12 @@ bool LLSelectMgr::linkObjects() return true; } + if (!LLSelectMgr::getInstance()->selectGetSameRegion()) + { + LLNotificationsUtil::add("CannotLinkAcrossRegions"); + return true; + } + LLSelectMgr::getInstance()->sendLink(); return true; @@ -2778,6 +2784,35 @@ BOOL LLSelectMgr::selectGetRootsModify() return TRUE; } +//----------------------------------------------------------------------------- +// selectGetSameRegion() - return TRUE if all objects are in same region +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetSameRegion() +{ + if (getSelection()->isEmpty()) + { + return TRUE; + } + LLViewerObject* object = getSelection()->getFirstObject(); + if (!object) + { + return FALSE; + } + LLViewerRegion* current_region = object->getRegion(); + + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) + { + LLSelectNode* node = *iter; + object = node->getObject(); + if (!node->mValid || !object || current_region != object->getRegion()) + { + return FALSE; + } + } + + return TRUE; +} //----------------------------------------------------------------------------- // selectGetNonPermanentEnforced() - return TRUE if all objects are not diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 2a893af266..7ef0032645 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -624,6 +624,9 @@ public: BOOL selectGetRootsModify(); BOOL selectGetModify(); + // returns TRUE if all objects are in same region + BOOL selectGetSameRegion(); + // returns TRUE if is all objects are non-permanent-enforced BOOL selectGetRootsNonPermanentEnforced(); BOOL selectGetNonPermanentEnforced(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 347409fcab..0a85344025 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -967,6 +967,8 @@ bool idle_startup() // Load media plugin cookies LLViewerMedia::loadCookieFile(); + LLRenderMuteList::getInstance()->loadFromFile(); + //------------------------------------------------- // Handle startup progress screen //------------------------------------------------- diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 46525e8455..cf18299b0b 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -38,6 +38,7 @@ #include "llfloaterautoreplacesettings.h" #include "llfloateravatar.h" #include "llfloateravatarpicker.h" +#include "llfloateravatarrendersettings.h" #include "llfloateravatartextures.h" #include "llfloaterbigpreview.h" #include "llfloaterbeacons.h" @@ -194,6 +195,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>); LLFloaterReg::add("avatar", "floater_avatar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatar>); LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>); + LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarRenderSettings>); LLFloaterReg::add("avatar_textures", "floater_avatar_textures.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarTextures>); LLFloaterReg::add("beacons", "floater_beacons.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBeacons>); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 61505b7c07..2d3b48bab3 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2724,8 +2724,16 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) return TRUE; } - if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask)) - ||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))) + if (gAgent.isInitialized() + && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL) + && gMenuBarView + && gMenuBarView->handleAcceleratorKey(key, mask)) + { + LLViewerEventRecorder::instance().logKeyEvent(key, mask); + return TRUE; + } + + if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)) { LLViewerEventRecorder::instance().logKeyEvent(key,mask); return TRUE; @@ -2855,8 +2863,16 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } // give menus a chance to handle unmodified accelerator keys - if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask)) - ||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))) + if (gAgent.isInitialized() + && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL) + && gMenuBarView + && gMenuBarView->handleAcceleratorKey(key, mask)) + { + LLViewerEventRecorder::instance().logKeyEvent(key, mask); + return TRUE; + } + + if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)) { return TRUE; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 760eee17f3..f6a16f7da1 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -728,7 +728,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this); } - mVisuallyMuteSetting = getSavedVisualMuteSettings(); + mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID())); } std::string LLVOAvatar::avString() const @@ -7076,7 +7076,9 @@ BOOL LLVOAvatar::isFullyLoaded() const bool LLVOAvatar::isTooComplex() const { bool too_complex; - if (isSelf() || mVisuallyMuteSetting == AV_ALWAYS_RENDER) + bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && gSavedSettings.getBOOL("AlwaysRenderFriends")); + + if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) { too_complex = false; } @@ -9230,25 +9232,12 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } } -//static -std::map<LLUUID, LLVOAvatar::VisualMuteSettings> LLVOAvatar::sVisuallyMuteSettingsMap; - void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set) { mVisuallyMuteSetting = set; mNeedsImpostorUpdate = TRUE; - sVisuallyMuteSettingsMap[getID()] = set; -} - -LLVOAvatar::VisualMuteSettings LLVOAvatar::getSavedVisualMuteSettings() -{ - std::map<LLUUID, VisualMuteSettings>::iterator iter = sVisuallyMuteSettingsMap.find(getID()); - if (iter != sVisuallyMuteSettingsMap.end()) - { - return iter->second; - } - return AV_RENDER_NORMALLY; + LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set)); } void LLVOAvatar::calcMutedAVColor() diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 73e4fbd108..bd89d4ef23 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -407,7 +407,6 @@ public: }; void setVisualMuteSettings(VisualMuteSettings set); VisualMuteSettings getVisualMuteSettings() { return mVisuallyMuteSetting; }; - VisualMuteSettings getSavedVisualMuteSettings(); U32 renderRigid(); U32 renderSkinned(); @@ -441,7 +440,6 @@ public: VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV - static std::map<LLUUID, VisualMuteSettings> sVisuallyMuteSettingsMap; //-------------------------------------------------------------------- // Morph masks //-------------------------------------------------------------------- diff --git a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml new file mode 100644 index 0000000000..03e812d36d --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<floater + can_resize="true" + positioning="cascading" + height="200" + min_height="100" + min_width="230" + layout="topleft" + name="floater_avatar_render_settings" + save_rect="true" + single_instance="true" + reuse_instance="true" + title="AVATAR RENDER SETTINGS" + width="300"> + <string + name="av_never_render" + value="Never"/> + <string + name="av_always_render" + value="Always"/> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="8" + right="-47" + label="Filter People" + max_length_chars="300" + name="people_filter_input" + text_color="Black" + text_pad_left="10" + top="4" /> + <menu_button + follows="top|right" + 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_pad="7" + menu_filename="menu_avatar_rendering_settings_add.xml" + menu_position="bottomleft" + name="plus_btn" + tool_tip="Actions on selected person" + top="3" + width="31" /> + <name_list + bottom="-8" + draw_heading="true" + follows="all" + left="8" + multi_select="false" + name="render_settings_list" + right="-8" + top="32"> + <name_list.columns + label="Name" + name="name" + relative_width="0.65" /> + <name_list.columns + label="Render setting" + name="setting" + relative_width="0.35" /> + </name_list> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml index 590d9d1844..612c894b59 100644 --- a/indra/newview/skins/default/xui/en/floater_tos.xml +++ b/indra/newview/skins/default/xui/en/floater_tos.xml @@ -70,7 +70,7 @@ top="32" word_wrap="true" width="552"> - You will need to go to my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you! + You will need to go to https://my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you! </text> <web_browser trusted_content="true" 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 2f60bab0b7..49b9ac273d 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -130,10 +130,13 @@ </menu_item_call> <menu_item_separator /> - + <context_menu + label="Render Avatar" + layout="topleft" + name="Render Avatar"> <menu_item_check name="RenderNormally" - label="Render Normally"> + label="Default"> <menu_item_check.on_check function="Avatar.CheckImpostorMode" parameter="0" /> @@ -142,26 +145,26 @@ parameter="0" /> </menu_item_check> <menu_item_check - name="DoNotRender" - label="Do Not Render"> + name="AlwaysRenderFully" + label="Always"> <menu_item_check.on_check function="Avatar.CheckImpostorMode" - parameter="1" /> + parameter="2" /> <menu_item_check.on_click function="Avatar.SetImpostorMode" - parameter="1" /> + parameter="2" /> </menu_item_check> <menu_item_check - name="AlwaysRenderFully" - label="Render Fully"> + name="DoNotRender" + label="Never"> <menu_item_check.on_check function="Avatar.CheckImpostorMode" - parameter="2" /> + parameter="1" /> <menu_item_check.on_click function="Avatar.SetImpostorMode" - parameter="2" /> + parameter="1" /> </menu_item_check> - + </context_menu> <menu_item_separator layout="topleft" name="Impostor seperator"/> 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 ddfff23410..c5426cb232 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -121,9 +121,13 @@ <menu_item_separator /> + <context_menu + label="Render Avatar" + layout="topleft" + name="Render Avatar"> <menu_item_check name="RenderNormally" - label="Render Normally"> + label="Default"> <menu_item_check.on_check function="Avatar.CheckImpostorMode" parameter="0" /> @@ -132,25 +136,26 @@ parameter="0" /> </menu_item_check> <menu_item_check - name="DoNotRender" - label="Do Not Render"> + name="AlwaysRenderFully" + label="Always"> <menu_item_check.on_check function="Avatar.CheckImpostorMode" - parameter="1" /> + parameter="2" /> <menu_item_check.on_click function="Avatar.SetImpostorMode" - parameter="1" /> + parameter="2" /> </menu_item_check> <menu_item_check - name="AlwaysRenderFully" - label="Render Fully"> + name="DoNotRender" + label="Never"> <menu_item_check.on_check function="Avatar.CheckImpostorMode" - parameter="2" /> + parameter="1" /> <menu_item_check.on_click function="Avatar.SetImpostorMode" - parameter="2" /> + parameter="1" /> </menu_item_check> + </context_menu> <menu_item_separator layout="topleft" name="Impostor seperator"/> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml new file mode 100644 index 0000000000..5163cd3115 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<context_menu + layout="topleft" + name="Settings"> + <menu_item_check + label="Default" + layout="topleft" + name="default"> + <on_click function="Settings.SetRendering" parameter="default"/> + <on_check function="Settings.IsSelected" parameter="default" /> + </menu_item_check> + <menu_item_check + label="Always render" + layout="topleft" + name="always_render"> + <on_click function="Settings.SetRendering" parameter="always"/> + <on_check function="Settings.IsSelected" parameter="always" /> + </menu_item_check> + <menu_item_check + label="Never render" + layout="topleft" + name="never_render"> + <on_click function="Settings.SetRendering" parameter="never"/> + <on_check function="Settings.IsSelected" parameter="never" /> + </menu_item_check> +</context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml new file mode 100644 index 0000000000..c64b24ed70 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + name="menu_settings_add.xml" + left="0" bottom="0" visible="false" + mouse_opaque="false"> + <menu_item_call + label="Always Render a Resident..." + name="add_avatar_always_render"> + <on_click + function="Settings.AddNewEntry" parameter="always"/> + </menu_item_call> + <menu_item_call + label="Never Render a Resident..." + name="add_avatar_never_render"> + <on_click + function="Settings.AddNewEntry" parameter="never"/> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a509adfcbc..3fcd91f89b 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -341,8 +341,7 @@ Initialization with the Marketplace failed because of a system or network error. type="alertmodal"> The transaction with the Marketplace failed with the following error : - Reason : '[ERROR_REASON]' - [ERROR_DESCRIPTION] + [ERROR_REASON][ERROR_DESCRIPTION] <usetemplate name="okbutton" @@ -1940,6 +1939,14 @@ Please make sure none are locked, and that you own all of them. <notification icon="alertmodal.tga" + name="CannotLinkAcrossRegions" + type="alertmodal"> +Objects cannot be linked across region boundaries. + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" name="CannotLinkDifferentOwners" type="alertmodal"> Unable to link because not all of the objects have the same owner. diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index 8d55e311f6..440c6613d5 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -432,18 +432,16 @@ top_pad="6" name="inventory_offer" width="150" /> - + <view_border + bevel_style="none" + height="0" + layout="topleft" + left="0" + name="cost_text_border" + top_pad="7" + width="492"/> </panel> - <view_border - bevel_style="none" - height="0" - layout="topleft" - left="13" - name="cost_text_border" - top_pad="5" - width="495"/> - <panel height="50" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 32cbbff8b7..4692a226d9 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -231,6 +231,34 @@ m </text> + <check_box + control_name="WindLightUseAtmosShaders" + height="16" + initial_value="true" + label="Atmospheric shaders" + layout="topleft" + left="30" + name="WindLightUseAtmosShaders" + top_delta="24" + width="280"> + <check_box.commit_callback + function="Pref.VertexShaderEnable" /> + </check_box> + + <check_box + control_name="RenderDeferred" + height="16" + initial_value="true" + label="Advanced Lighting Model" + layout="topleft" + left="30" + name="UseLightShaders" + top_delta="24" + width="256"> + <check_box.commit_callback + function="Pref.VertexShaderEnable" /> + </check_box> + <slider control_name="IndirectMaxComplexity" tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll" @@ -246,7 +274,7 @@ max_val="101" name="IndirectMaxComplexity" show_text="false" - top_delta="24" + top_delta="60" width="300"> <slider.commit_callback function="Pref.UpdateIndirectMaxComplexity" @@ -265,34 +293,28 @@ width="65"> 0 </text> - <check_box - control_name="WindLightUseAtmosShaders" + control_name="AlwaysRenderFriends" height="16" initial_value="true" - label="Atmospheric shaders" + label="Always Render Friends" layout="topleft" left="30" - name="WindLightUseAtmosShaders" + name="AlwaysRenderFriends" top_delta="24" - width="280"> - <check_box.commit_callback - function="Pref.VertexShaderEnable" /> + width="256"> </check_box> - - <check_box - control_name="RenderDeferred" - height="16" - initial_value="true" - label="Advanced Lighting Model" + <button + height="23" + label="Exceptions..." layout="topleft" - left="30" - name="UseLightShaders" + left="48" + name="RenderExceptionsButton" top_delta="24" - width="256"> - <check_box.commit_callback - function="Pref.VertexShaderEnable" /> - </check_box> + width="100"> + <button.commit_callback + function="Pref.RenderExceptions"/> + </button> <!-- End of Basic Settings block --> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e3e770444c..5f686a87be 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3885,7 +3885,7 @@ Abuse Report</string> <string name="server_is_down"> Despite our best efforts, something unexpected has gone wrong. -Please check status.secondlifegrid.net to see if there is a known problem with the service. +Please check http://status.secondlifegrid.net to see if there is a known problem with the service. If you continue to experience problems, please check your network and firewall setup. </string> |