From 2b219a0bd57c2ee51f3fc3c968bef915d7c46e7e Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 13 Jul 2020 15:36:35 +0300 Subject: SL-13582 FIXED The Favorites bar overflow list is shifted after clicking any button on the context menu --- indra/llui/llmenugl.cpp | 21 +++++++++++++-------- indra/llui/llmenugl.h | 2 +- indra/newview/llfavoritesbar.cpp | 12 ++++++++++-- indra/newview/llfavoritesbar.h | 5 +++++ 4 files changed, 29 insertions(+), 11 deletions(-) (limited to 'indra') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 5568a84494..2c28b7943e 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3244,7 +3244,7 @@ void hide_top_view( LLView* view ) // x and y are the desired location for the popup, in the spawning_view's // coordinate frame, NOT necessarily the mouse location // static -void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) +void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x, S32 mouse_y) { const S32 CURSOR_HEIGHT = 22; // Approximate "normal" cursor size const S32 CURSOR_WIDTH = 12; @@ -3275,12 +3275,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) } } - // Save click point for detecting cursor moves before mouse-up. - // Must be in local coords to compare with mouseUp events. - // If the mouse doesn't move, the menu will stay open ala the Mac. - // See also LLContextMenu::show() - S32 mouse_x, mouse_y; - // Resetting scrolling position if (menu->isScrollable() && menu->isScrollPositionOnShowReset()) { @@ -3291,7 +3285,18 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) menu->needsArrange(); menu->arrangeAndClear(); - LLUI::getInstance()->getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y); + if ((mouse_x == 0) || (mouse_y == 0)) + + { + // Save click point for detecting cursor moves before mouse-up. + // Must be in local coords to compare with mouseUp events. + // If the mouse doesn't move, the menu will stay open ala the Mac. + // See also LLContextMenu::show() + + LLUI::getInstance()->getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y); + } + + LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y); const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getRect(); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 1f11f26192..805620bf9b 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -510,7 +510,7 @@ public: void createJumpKeys(); // Show popup at a specific location, in the spawn_view's coordinate frame - static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y); + static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x = 0, S32 mouse_y = 0); // Whether to drop shadow menu bar void setDropShadowed( const BOOL shadowed ); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 17952349dc..711b3c61e5 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -384,6 +384,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) mUpdateDropDownItems(true), mRestoreOverflowMenu(false), mGetPrevItems(true), + mMouseX(0), + mMouseY(0), mItemsChangedTimer() { // Register callback for menus with current registrar (will be parent panel's registrar) @@ -399,7 +401,7 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) //make chevron button LLTextBox::Params more_button_params(p.more_button); mMoreTextBox = LLUICtrlFactory::create (more_button_params); - mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); + mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this)); addChild(mMoreTextBox); mDropDownItemsCount = 0; @@ -975,6 +977,12 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it return TRUE; } +void LLFavoritesBarCtrl::onMoreTextBoxClicked() +{ + LLUI::getInstance()->getMousePositionScreen(&mMouseX, &mMouseY); + showDropDownMenu(); +} + void LLFavoritesBarCtrl::showDropDownMenu() { if (mOverflowMenuHandle.isDead()) @@ -1130,7 +1138,7 @@ void LLFavoritesBarCtrl::positionAndShowMenu(LLToggleableMenu* menu) } } - LLMenuGL::showPopup(this, menu, menu_x, menu_y); + LLMenuGL::showPopup(this, menu, menu_x, menu_y, mMouseX, mMouseY); } void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id) diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index d93161fd7a..2951b5cedf 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -96,6 +96,8 @@ protected: void showDropDownMenu(); + void onMoreTextBoxClicked(); + LLHandle mOverflowMenuHandle; LLHandle mContextMenuHandle; @@ -163,6 +165,9 @@ private: BOOL mTabsHighlightEnabled; + S32 mMouseX; + S32 mMouseY; + boost::signals2::connection mEndDragConnection; }; -- cgit v1.2.3 From 6fdc9da2d3105723a7a3bd3bbc468a5d3c38dcb0 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 14 Jul 2020 17:00:48 +0300 Subject: SL-13587 FIXED The "Picks" floater is opened on the Viewer login page --- indra/newview/llgroupactions.cpp | 6 ++++++ indra/newview/llpanelpicks.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+) (limited to 'indra') diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index d2bd716f55..12d82d101f 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -39,6 +39,7 @@ #include "llfloaterimcontainer.h" #include "llimview.h" // for gIMMgr #include "llnotificationsutil.h" +#include "llstartup.h" #include "llstatusbar.h" // can_afford_transaction() #include "groupchatlistener.h" @@ -55,6 +56,11 @@ public: bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { + if (LLStartUp::getStartupState() < STATE_STARTED) + { + return true; + } + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableGroupInfo")) { LLNotificationsUtil::add("NoGroupInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index c39df3fe8b..4762e15d8f 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -37,6 +37,7 @@ #include "llfloatersidepanelcontainer.h" #include "llfloaterworldmap.h" #include "llnotificationsutil.h" +#include "llstartup.h" #include "lltexturectrl.h" #include "lltoggleablemenu.h" #include "lltrans.h" @@ -84,6 +85,11 @@ public: bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { + if (LLStartUp::getStartupState() < STATE_STARTED) + { + return true; + } + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks")) { LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); @@ -198,6 +204,11 @@ public: bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { + if (LLStartUp::getStartupState() < STATE_STARTED) + { + return true; + } + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds")) { LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); -- cgit v1.2.3 From 2c93c14c9d6cf6940169d33b806dede90e60033f Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 16 Jul 2020 17:51:06 +0300 Subject: SL-13609 Better indicate which conversation is active in Conversations floater --- indra/newview/llfloaterimcontainer.cpp | 12 ++++++- indra/newview/llfloaterimsessiontab.cpp | 38 +++++++++++++++++++++ indra/newview/llfloaterimsessiontab.h | 2 ++ .../default/textures/icons/nearby_chat_icon.png | Bin 399 -> 1035 bytes .../skins/default/xui/en/floater_im_session.xml | 32 ++++++++++++++++- 5 files changed, 82 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 21420b122b..540d2366a9 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -304,12 +304,15 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp, LLIconCtrl* icon = 0; + bool is_in_group = gAgent.isInGroup(session_id, TRUE); + LLUUID icon_id; - if(gAgent.isInGroup(session_id, TRUE)) + if (is_in_group) { LLGroupIconCtrl::Params icon_params; icon_params.group_id = session_id; icon = LLUICtrlFactory::instance().create(icon_params); + icon_id = session_id; mSessions[session_id] = floaterp; floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id)); @@ -321,11 +324,18 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp, LLAvatarIconCtrl::Params icon_params; icon_params.avatar_id = avatar_id; icon = LLUICtrlFactory::instance().create(icon_params); + icon_id = avatar_id; mSessions[session_id] = floaterp; floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id)); } + LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id); + if (floater) + { + floater->updateChatIcon(icon_id); + } + // forced resize of the floater LLRect wrapper_rect = this->mTabContainer->getLocalRect(); floaterp->setRect(wrapper_rect); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 3aee08482b..c75109db36 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -32,6 +32,8 @@ #include "llagent.h" #include "llagentcamera.h" #include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llgroupiconctrl.h" #include "llchatentry.h" #include "llchathistory.h" #include "llchiclet.h" @@ -45,6 +47,9 @@ #include "llfloaterimnearbychat.h" const F32 REFRESH_INTERVAL = 1.0f; +const std::string ICN_GROUP("group_chat_icon"); +const std::string ICN_NEARBY("nearby_chat_icon"); +const std::string ICN_AVATAR("avatar_icon"); void cb_group_do_nothing() { @@ -693,6 +698,39 @@ void LLFloaterIMSessionTab::updateSessionName(const std::string& name) mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name); } +void LLFloaterIMSessionTab::updateChatIcon(const LLUUID& id) +{ + if (mSession) + { + if (mSession->isP2PSessionType()) + { + LLAvatarIconCtrl* icon = getChild(ICN_AVATAR); + icon->setVisible(true); + icon->setValue(id); + } + if (mSession->isAdHocSessionType()) + { + LLGroupIconCtrl* icon = getChild(ICN_GROUP); + icon->setVisible(true); + } + if (mSession->isGroupSessionType()) + { + LLGroupIconCtrl* icon = getChild(ICN_GROUP); + icon->setVisible(true); + icon->setValue(id); + } + } + else + { + if (mIsNearbyChat) + { + LLIconCtrl* icon = getChild(ICN_NEARBY); + icon->setVisible(true); + } + } + +} + void LLFloaterIMSessionTab::hideAllStandardButtons() { for (S32 i = 0; i < BUTTON_COUNT; i++) diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 1b4922fd73..169eb1cf7f 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -103,6 +103,8 @@ public: void restoreFloater(); void saveCollapsedState(); + void updateChatIcon(const LLUUID& id); + LLView* getChatHistory(); protected: diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png index 5ac4258b9d..2cb577776d 100644 Binary files a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png and b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png differ diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index c64ee5565a..15f02ab9c3 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -267,6 +267,36 @@ right="-1"> + + + -- cgit v1.2.3 From 44906ac0d44d3c3d1dc6dbf0d5e90926529e108d Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 17 Jul 2020 20:28:02 +0300 Subject: SL-13507 Viewer should log resolution of all associated displays --- indra/llwindow/llwindow.cpp | 10 ++++++++++ indra/llwindow/llwindow.h | 3 +++ indra/llwindow/llwindowwin32.cpp | 39 +++++++++++++++++++++++++++++++++++++++ indra/llwindow/llwindowwin32.h | 1 + indra/newview/llappviewer.cpp | 6 ++++++ 5 files changed, 59 insertions(+) (limited to 'indra') diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 1b24250618..637ed10008 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -263,6 +263,16 @@ std::vector LLWindow::getDynamicFallbackFontList() #endif } +// static +std::vector LLWindow::getDisplaysResolutionList() +{ +#if LL_WINDOWS + return LLWindowWin32::getDisplaysResolutionList(); +#else + return std::vector(); +#endif +} + #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400) #define UTF16_IS_LOW_SURROGATE(U) ((U16)((U) - 0xDC00) < 0x0400) #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index a05ba8cbba..bb4e534b60 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -168,6 +168,9 @@ public: // Get system UI size based on DPI (for 96 DPI UI size should be 1.0) virtual F32 getSystemUISize() { return 1.0; } + + static std::vector getDisplaysResolutionList(); + protected: LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); virtual ~LLWindow(); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 0b3936f8a5..3cbba59ed7 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -400,6 +400,39 @@ LLWinImm::~LLWinImm() } +class LLMonitorInfo +{ +public: + + std::vector getResolutionsList() { return mResList; } + + LLMonitorInfo() + { + EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); + } + +private: + + static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData) + { + int monitor_width = lprcMonitor->right - lprcMonitor->left; + int monitor_height = lprcMonitor->bottom - lprcMonitor->top; + + std::ostringstream sstream; + sstream << monitor_width << "x" << monitor_height;; + std::string res = sstream.str(); + + LLMonitorInfo* pThis = reinterpret_cast(pData); + pThis->mResList.push_back(res); + + return TRUE; + } + + std::vector mResList; +}; + +static LLMonitorInfo sMonitorInfo; + LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, @@ -4218,6 +4251,12 @@ F32 LLWindowWin32::getSystemUISize() return scale_value; } +//static +std::vector LLWindowWin32::getDisplaysResolutionList() +{ + return sMonitorInfo.getResolutionsList(); +} + //static std::vector LLWindowWin32::getDynamicFallbackFontList() { diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 9cd16eb993..b1e8350a78 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -114,6 +114,7 @@ public: LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); + static std::vector getDisplaysResolutionList(); static std::vector getDynamicFallbackFontList(); static void setDPIAwareness(); protected: diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7c0124322c..d82e6fc58c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3490,6 +3490,12 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); + std::vector resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList(); + for (auto res_iter : resolutions) + { + gDebugInfo["DisplayInfo"].append(res_iter); + } + writeDebugInfo(); // Save out debug_info.log early, in case of crash. } -- cgit v1.2.3 From 4d27b11a160e86b3d2f2ebb56f5b308ed6a7704a Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Mon, 20 Jul 2020 17:09:04 +0300 Subject: SL-13507 Viewer should log resolution of all associated displays --- indra/llwindow/llwindow.cpp | 2 ++ indra/llwindow/llwindowmacosx.cpp | 30 ++++++++++++++++++++++++++++++ indra/llwindow/llwindowmacosx.h | 2 ++ 3 files changed, 34 insertions(+) (limited to 'indra') diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 637ed10008..5112e4d3db 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -268,6 +268,8 @@ std::vector LLWindow::getDisplaysResolutionList() { #if LL_WINDOWS return LLWindowWin32::getDisplaysResolutionList(); +#elif LL_DARWIN + return LLWindowMacOSX::getDisplaysResolutionList(); #else return std::vector(); #endif diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 2604a23c85..0d0607a0bb 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -41,6 +41,7 @@ #include #include #include +#include extern BOOL gDebugWindowProc; BOOL gHiDPISupport = TRUE; @@ -1911,6 +1912,35 @@ void LLWindowMacOSX::interruptLanguageTextInput() commitCurrentPreedit(mGLView); } +std::vector LLWindowMacOSX::getDisplaysResolutionList() +{ + std::vector resolution_list; + + CGDirectDisplayID display_ids[10]; + uint32_t found_displays = 0; + CGError err = CGGetActiveDisplayList(10, display_ids, &found_displays); + + if (kCGErrorSuccess != err) + { + LL_WARNS() << "Couldn't get a list of active displays" << LL_ENDL; + return std::vector(); + } + + for (uint32_t i = 0; i < found_displays; i++) + { + S32 monitor_width = CGDisplayPixelsWide(display_ids[i]); + S32 monitor_height = CGDisplayPixelsHigh(display_ids[i]); + + std::ostringstream sstream; + sstream << monitor_width << "x" << monitor_height;; + std::string res = sstream.str(); + + resolution_list.push_back(res); + } + + return resolution_list; +} + //static std::vector LLWindowMacOSX::getDynamicFallbackFontList() { diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 24651027e8..bf45238c8d 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -114,6 +114,8 @@ public: /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); /*virtual*/ F32 getSystemUISize(); + static std::vector getDisplaysResolutionList(); + static std::vector getDynamicFallbackFontList(); // Provide native key event data -- cgit v1.2.3 From 9d2c405ee419af3c316939a7fe12fbd97ce49f9b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 17 Jul 2020 23:19:37 +0300 Subject: SL-13516 Move dupplicated functionality of evironment editors into separate class --- indra/newview/CMakeLists.txt | 2 + indra/newview/llfloatereditenvironmentbase.cpp | 479 +++++++++++++++++++++++++ indra/newview/llfloatereditenvironmentbase.h | 148 ++++++++ indra/newview/llfloatereditextdaycycle.cpp | 396 ++------------------ indra/newview/llfloatereditextdaycycle.h | 48 +-- indra/newview/llfloaterfixedenvironment.cpp | 357 +----------------- indra/newview/llfloaterfixedenvironment.h | 76 +--- indra/newview/llpaneleditsky.h | 2 +- indra/newview/llpaneleditwater.h | 2 +- 9 files changed, 683 insertions(+), 827 deletions(-) create mode 100644 indra/newview/llfloatereditenvironmentbase.cpp create mode 100644 indra/newview/llfloatereditenvironmentbase.h (limited to 'indra') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 33fa186a2e..6164e717c5 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -235,6 +235,7 @@ set(viewer_SOURCE_FILES llfloaterconversationpreview.cpp llfloaterdeleteprefpreset.cpp llfloaterdestinations.cpp + llfloatereditenvironmentbase.cpp llfloatereditextdaycycle.cpp llfloaterenvironmentadjust.cpp llfloaterevent.cpp @@ -865,6 +866,7 @@ set(viewer_HEADER_FILES llfloaterconversationpreview.h llfloaterdeleteprefpreset.h llfloaterdestinations.h + llfloatereditenvironmentbase.h llfloatereditextdaycycle.h llfloaterenvironmentadjust.h llfloaterevent.h diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp new file mode 100644 index 0000000000..2a38f18b73 --- /dev/null +++ b/indra/newview/llfloatereditenvironmentbase.cpp @@ -0,0 +1,479 @@ +/** + * @file llfloatereditenvironmentbase.cpp + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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 "llfloatereditenvironmentbase.h" + +#include + +// libs +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llfilepicker.h" +#include "llsettingspicker.h" +#include "llviewerparcelmgr.h" + +// newview +#include "llsettingssky.h" +#include "llsettingswater.h" + +#include "llenvironment.h" +#include "llagent.h" +#include "llparcel.h" + +#include "llsettingsvo.h" +#include "llinventorymodel.h" + +namespace +{ + const std::string ACTION_APPLY_LOCAL("apply_local"); + const std::string ACTION_APPLY_PARCEL("apply_parcel"); + const std::string ACTION_APPLY_REGION("apply_region"); +} + +//========================================================================= +const std::string LLFloaterEditEnvironmentBase::KEY_INVENTORY_ID("inventory_id"); + + +//========================================================================= + +class LLFixedSettingCopiedCallback : public LLInventoryCallback +{ +public: + LLFixedSettingCopiedCallback(LLHandle handle) : mHandle(handle) {} + + virtual void fire(const LLUUID& inv_item_id) + { + if (!mHandle.isDead()) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); + if (item) + { + LLFloaterEditEnvironmentBase* floater = (LLFloaterEditEnvironmentBase*)mHandle.get(); + floater->onInventoryCreated(item->getAssetUUID(), inv_item_id); + } + } + } + +private: + LLHandle mHandle; +}; + +//========================================================================= +LLFloaterEditEnvironmentBase::LLFloaterEditEnvironmentBase(const LLSD &key) : + LLFloater(key), + mInventoryId(), + mInventoryItem(nullptr), + mIsDirty(false), + mCanCopy(false), + mCanMod(false), + mCanTrans(false), + mCanSave(false) +{ +} + +LLFloaterEditEnvironmentBase::~LLFloaterEditEnvironmentBase() +{ +} + +void LLFloaterEditEnvironmentBase::onFocusReceived() +{ + if (isInVisibleChain()) + { + updateEditEnvironment(); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); + } +} + +void LLFloaterEditEnvironmentBase::onFocusLost() +{ +} + +void LLFloaterEditEnvironmentBase::loadInventoryItem(const LLUUID &inventoryId, bool can_trans) +{ + if (inventoryId.isNull()) + { + mInventoryItem = nullptr; + mInventoryId.setNull(); + mCanMod = true; + mCanCopy = true; + mCanTrans = true; + return; + } + + mInventoryId = inventoryId; + LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; + mInventoryItem = gInventory.getItem(mInventoryId); + + if (!mInventoryItem) + { + LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; + LLNotificationsUtil::add("CantFindInvItem"); + closeFloater(); + + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + if (mInventoryItem->getAssetUUID().isNull()) + { + LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; + LLNotificationsUtil::add("UnableEditItem"); + closeFloater(); + + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + mCanSave = true; + mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); + mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); + mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + + mExpectingAssetId = mInventoryItem->getAssetUUID(); + LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), + [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); +} + + +void LLFloaterEditEnvironmentBase::checkAndConfirmSettingsLoss(LLFloaterEditEnvironmentBase::on_confirm_fn cb) +{ + if (isDirty()) + { + LLSD args(LLSDMap("TYPE", getEditSettings()->getSettingsType()) + ("NAME", getEditSettings()->getName())); + + // create and show confirmation textbox + LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), + [cb](const LLSD¬if, const LLSD&resp) + { + S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); + if (opt == 0) + cb(); + }); + } + else if (cb) + { + cb(); + } +} + +void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) +{ + if (asset_id != mExpectingAssetId) + { + LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL; + return; + } + mExpectingAssetId.setNull(); + clearDirtyFlag(); + + if (!settings || status) + { + LLSD args; + args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown"; + LLNotificationsUtil::add("FailedToFindSettings", args); + closeFloater(); + return; + } + + if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE)) + { + mCanSave = false; + mCanCopy = false; + mCanMod = false; + mCanTrans = false; + } + else + { + if (mInventoryItem) + settings->setName(mInventoryItem->getName()); + + if (mCanCopy) + settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); + else + settings->setFlag(LLSettingsBase::FLAG_NOCOPY); + + if (mCanMod) + settings->clearFlag(LLSettingsBase::FLAG_NOMOD); + else + settings->setFlag(LLSettingsBase::FLAG_NOMOD); + + if (mCanTrans) + settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); + else + settings->setFlag(LLSettingsBase::FLAG_NOTRANS); + } + + setEditSettingsAndUpdate(settings); +} + +void LLFloaterEditEnvironmentBase::onButtonImport() +{ + checkAndConfirmSettingsLoss([this](){ doImportFromDisk(); }); +} + +void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + std::string settings_name = response["message"].asString(); + + LLInventoryObject::correctInventoryName(settings_name); + if (settings_name.empty()) + { + // Ideally notification should disable 'OK' button if name won't fit our requirements, + // for now either display notification, or use some default name + settings_name = "Unnamed"; + } + + if (mCanMod) + { + doApplyCreateNewInventory(settings_name, settings); + } + else if (mInventoryItem) + { + const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + LLUUID parent_id = mInventoryItem->getParentUUID(); + if (marketplacelistings_id == parent_id) + { + parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); + } + + LLPointer cb = new LLFixedSettingCopiedCallback(getHandle()); + copy_inventory_item( + gAgent.getID(), + mInventoryItem->getPermissions().getOwner(), + mInventoryItem->getUUID(), + parent_id, + settings_name, + cb); + } + else + { + LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL; + } + } +} + +void LLFloaterEditEnvironmentBase::onClickCloseBtn(bool app_quitting) +{ + if (!app_quitting) + checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); }); + else + closeFloater(); +} + +void LLFloaterEditEnvironmentBase::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings) +{ + if (mInventoryItem) + { + LLUUID parent_id = mInventoryItem->getParentUUID(); + U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); + LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } + else + { + LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); + // This method knows what sort of settings object to create. + LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } +} + +void LLFloaterEditEnvironmentBase::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings) +{ + LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL; + if (mInventoryId.isNull()) + { + LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } + else + { + LLSettingsVOBase::updateInventoryItem(settings, mInventoryId, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); + } +} + +void LLFloaterEditEnvironmentBase::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings) +{ + U32 flags(0); + + if (mInventoryItem) + { + if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) + flags |= LLSettingsBase::FLAG_NOMOD; + if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + flags |= LLSettingsBase::FLAG_NOTRANS; + } + + flags |= settings->getFlags(); + settings->setFlag(flags); + + if (where == ACTION_APPLY_LOCAL) + { + settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings); + } + else if (where == ACTION_APPLY_PARCEL) + { + LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); + + if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) + { + LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL; + LLNotificationsUtil::add("WLParcelApplyFail"); + return; + } + + if (mInventoryItem && !isDirty()) + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); + } + else if (settings->getSettingsType() == "sky") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); + } + else if (settings->getSettingsType() == "water") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); + } + else if (settings->getSettingsType() == "day") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); + } + } + else if (where == ACTION_APPLY_REGION) + { + if (mInventoryItem && !isDirty()) + { + LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); + } + else if (settings->getSettingsType() == "sky") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); + } + else if (settings->getSettingsType() == "water") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); + } + else if (settings->getSettingsType() == "day") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); + } + } + else + { + LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; + return; + } + +} + +void LLFloaterEditEnvironmentBase::doCloseInventoryFloater(bool quitting) +{ + LLFloater* floaterp = mInventoryFloater.get(); + + if (floaterp) + { + floaterp->closeFloater(quitting); + } +} + +void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; + + if (inventory_id.isNull() || !results["success"].asBoolean()) + { + LLNotificationsUtil::add("CantCreateInventory"); + return; + } + onInventoryCreated(asset_id, inventory_id); +} + +void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id) +{ + bool can_trans = true; + if (mInventoryItem) + { + LLPermissions perms = mInventoryItem->getPermissions(); + + LLInventoryItem *created_item = gInventory.getItem(mInventoryId); + + if (created_item) + { + can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID()); + created_item->setPermissions(perms); + created_item->updateServer(false); + } + } + + clearDirtyFlag(); + setFocus(TRUE); // Call back the focus... + loadInventoryItem(inventory_id, can_trans); +} + +void LLFloaterEditEnvironmentBase::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; + + clearDirtyFlag(); + if (inventory_id != mInventoryId) + { + loadInventoryItem(inventory_id); + } +} + +void LLFloaterEditEnvironmentBase::onPanelDirtyFlagChanged(bool value) +{ + if (value) + setDirtyFlag(); +} + +//------------------------------------------------------------------------- +bool LLFloaterEditEnvironmentBase::canUseInventory() const +{ + return LLEnvironment::instance().isInventoryEnabled(); +} + +bool LLFloaterEditEnvironmentBase::canApplyRegion() const +{ + return gAgent.canManageEstate(); +} + +bool LLFloaterEditEnvironmentBase::canApplyParcel() const +{ + return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); +} + +//========================================================================= diff --git a/indra/newview/llfloatereditenvironmentbase.h b/indra/newview/llfloatereditenvironmentbase.h new file mode 100644 index 0000000000..7c7cf5bdcd --- /dev/null +++ b/indra/newview/llfloatereditenvironmentbase.h @@ -0,0 +1,148 @@ +/** + * @file llfloatereditenvironmentbase.h + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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_FLOATEREDITENVIRONMENTBASE_H +#define LL_FLOATEREDITENVIRONMENTBASE_H + +#include "llfloater.h" +#include "llsettingsbase.h" +#include "llflyoutcombobtn.h" +#include "llinventory.h" + +#include "boost/signals2.hpp" + +class LLTabContainer; +class LLButton; +class LLLineEditor; +class LLFloaterSettingsPicker; +class LLFixedSettingCopiedCallback; + +class LLFloaterEditEnvironmentBase : public LLFloater +{ + LOG_CLASS(LLFloaterEditEnvironmentBase); + + friend class LLFixedSettingCopiedCallback; + +public: + static const std::string KEY_INVENTORY_ID; + + LLFloaterEditEnvironmentBase(const LLSD &key); + ~LLFloaterEditEnvironmentBase(); + + virtual void onFocusReceived() override; + virtual void onFocusLost() override; + + virtual LLSettingsBase::ptr_t getEditSettings() const = 0; + + virtual BOOL isDirty() const override { return getIsDirty(); } + +protected: + typedef std::function on_confirm_fn; + + virtual void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) = 0; + virtual void updateEditEnvironment() = 0; + + virtual LLFloaterSettingsPicker *getSettingsPicker() = 0; + + void loadInventoryItem(const LLUUID &inventoryId, bool can_trans = true); + + void checkAndConfirmSettingsLoss(on_confirm_fn cb); + + virtual void doImportFromDisk() = 0; + virtual void doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings); + virtual void doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings); + virtual void doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings); + void doCloseInventoryFloater(bool quitting = false); + + bool canUseInventory() const; + bool canApplyRegion() const; + bool canApplyParcel() const; + + LLUUID mInventoryId; + LLInventoryItem * mInventoryItem; + LLHandle mInventoryFloater; + bool mCanCopy; + bool mCanMod; + bool mCanTrans; + bool mCanSave; + + bool mIsDirty; + + void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); + void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + + bool getIsDirty() const { return mIsDirty; } + void setDirtyFlag() { mIsDirty = true; } + virtual void clearDirtyFlag() = 0; + + void onPanelDirtyFlagChanged(bool); + + virtual void onClickCloseBtn(bool app_quitting = false) override; + void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings); + void onButtonImport(); + + void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status); + +private: + LLUUID mExpectingAssetId; // for asset load confirmation +}; + +class LLSettingsEditPanel : public LLPanel +{ +public: + virtual void setSettings(const LLSettingsBase::ptr_t &) = 0; + + typedef boost::signals2::signal on_dirty_charged_sg; + typedef boost::signals2::connection connection_t; + + inline bool getIsDirty() const { return mIsDirty; } + inline void setIsDirty() { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } + inline void clearIsDirty() { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } + + inline bool getCanChangeSettings() const { return mCanEdit; } + inline void setCanChangeSettings(bool flag) { mCanEdit = flag; } + + inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb) { return mOnDirtyChanged.connect(cb); } + + +protected: + LLSettingsEditPanel() : + LLPanel(), + mIsDirty(false), + mOnDirtyChanged() + {} + +private: + void onTextureChanged(LLUUID &inventory_item_id); + + bool mIsDirty; + bool mCanEdit; + + on_dirty_charged_sg mOnDirtyChanged; +}; + +#endif // LL_FLOATERENVIRONMENTBASE_H diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index ea22043de8..0501c287ad 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -125,7 +125,6 @@ namespace { } //========================================================================= -const std::string LLFloaterEditExtDayCycle::KEY_INVENTORY_ID("inventory_id"); const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context"); const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length"); const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod"); @@ -133,7 +132,7 @@ const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod"); const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory"); const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel"); const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region"); - +/* //========================================================================= class LLDaySettingCopiedCallback : public LLInventoryCallback @@ -156,12 +155,12 @@ public: private: LLHandle mHandle; -}; +};*/ //========================================================================= LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) : - LLFloater(key), + LLFloaterEditEnvironmentBase(key), mFlyoutControl(nullptr), mDayLength(0), mCurrentTrack(1), @@ -170,19 +169,12 @@ LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) : mFramesSlider(nullptr), mCurrentTimeLabel(nullptr), mImportButton(nullptr), - mInventoryId(), - mInventoryItem(nullptr), mLoadFrame(nullptr), mSkyBlender(), mWaterBlender(), mScratchSky(), mScratchWater(), mIsPlaying(false), - mIsDirty(false), - mCanSave(false), - mCanCopy(false), - mCanMod(false), - mCanTrans(false), mCloneTrack(nullptr), mLoadTrack(nullptr), mClearTrack(nullptr) @@ -425,19 +417,6 @@ void LLFloaterEditExtDayCycle::onClose(bool app_quitting) } } -void LLFloaterEditExtDayCycle::onFocusReceived() -{ - if (isInVisibleChain()) - { - updateEditEnvironment(); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); - } -} - -void LLFloaterEditExtDayCycle::onFocusLost() -{ -} - void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility) { @@ -488,6 +467,10 @@ void LLFloaterEditExtDayCycle::refresh() LLFloater::refresh(); } +void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) +{ + setEditDayCycle(std::dynamic_pointer_cast(settings)); +} void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday) { @@ -700,63 +683,6 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data) } } -void LLFloaterEditExtDayCycle::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) - { - std::string settings_name = response["message"].asString(); - - LLInventoryObject::correctInventoryName(settings_name); - if (settings_name.empty()) - { - // Ideally notification should disable 'OK' button if name won't fit our requirements, - // for now either display notification, or use some default name - settings_name = "Unnamed"; - } - - if (mCanMod) - { - doApplyCreateNewInventory(day, settings_name); - } - else if (mInventoryItem) - { - const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); - LLUUID parent_id = mInventoryItem->getParentUUID(); - if (marketplacelistings_id == parent_id) - { - parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - } - - LLPointer cb = new LLDaySettingCopiedCallback(getHandle()); - copy_inventory_item( - gAgent.getID(), - mInventoryItem->getPermissions().getOwner(), - mInventoryItem->getUUID(), - parent_id, - settings_name, - cb); - } - else - { - LL_WARNS() << "Failed to copy day setting" << LL_ENDL; - } - } -} - -void LLFloaterEditExtDayCycle::onClickCloseBtn(bool app_quitting /*= false*/) -{ - if (!app_quitting) - checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); }); - else - closeFloater(); -} - -void LLFloaterEditExtDayCycle::onButtonImport() -{ - checkAndConfirmSettingsLoss([this]() { doImportFromDisk(); }); -} - void LLFloaterEditExtDayCycle::onButtonLoadFrame() { doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null); @@ -1053,35 +979,6 @@ void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask) selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR); } - -void LLFloaterEditExtDayCycle::onPanelDirtyFlagChanged(bool value) -{ - if (value) - setDirtyFlag(); -} - -void LLFloaterEditExtDayCycle::checkAndConfirmSettingsLoss(on_confirm_fn cb) -{ - if (isDirty()) - { - LLSD args(LLSDMap("TYPE", mEditDay->getSettingsType()) - ("NAME", mEditDay->getName())); - - // create and show confirmation textbox - LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), - [cb](const LLSD¬if, const LLSD&resp) - { - S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); - if (opt == 0) - cb(); - }); - } - else if (cb) - { - cb(); - } -} - void LLFloaterEditExtDayCycle::onTimeSliderCallback() { stopPlay(); @@ -1435,106 +1332,6 @@ LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSi return mCommitSignal.connect(cb); } -void LLFloaterEditExtDayCycle::loadInventoryItem(const LLUUID &inventoryId, bool can_trans) -{ - if (inventoryId.isNull()) - { - mInventoryItem = nullptr; - mInventoryId.setNull(); - mCanSave = true; - mCanCopy = true; - mCanMod = true; - mCanTrans = true; - return; - } - - mInventoryId = inventoryId; - LL_INFOS("ENVDAYEDIT") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; - mInventoryItem = gInventory.getItem(mInventoryId); - - if (!mInventoryItem) - { - LL_WARNS("ENVDAYEDIT") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; - - LLNotificationsUtil::add("CantFindInvItem"); - closeFloater(); - mInventoryId.setNull(); - mInventoryItem = nullptr; - return; - } - - if (mInventoryItem->getAssetUUID().isNull()) - { - LL_WARNS("ENVDAYEDIT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; - - LLNotificationsUtil::add("UnableEditItem"); - closeFloater(); - - mInventoryId.setNull(); - mInventoryItem = nullptr; - return; - } - - mCanSave = true; - mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); - mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); - mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); - - mExpectingAssetId = mInventoryItem->getAssetUUID(); - LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), - [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - -void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) -{ - if (asset_id != mExpectingAssetId) - { - LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL; - return; - } - mExpectingAssetId.setNull(); - clearDirtyFlag(); - - if (!settings || status) - { - LLSD args; - args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown"; - LLNotificationsUtil::add("FailedToFindSettings", args); - closeFloater(); - return; - } - - if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE)) - { - mCanSave = false; - mCanCopy = false; - mCanMod = false; - mCanTrans = false; - } - else - { - if (mCanCopy) - settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); - else - settings->setFlag(LLSettingsBase::FLAG_NOCOPY); - - if (mCanMod) - settings->clearFlag(LLSettingsBase::FLAG_NOMOD); - else - settings->setFlag(LLSettingsBase::FLAG_NOMOD); - - if (mCanTrans) - settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); - else - settings->setFlag(LLSettingsBase::FLAG_NOTRANS); - - if (mInventoryItem) - settings->setName(mInventoryItem->getName()); - } - - setEditDayCycle(std::dynamic_pointer_cast(settings)); -} - void LLFloaterEditExtDayCycle::updateEditEnvironment(void) { if (!mEditDay) @@ -1670,93 +1467,6 @@ void LLFloaterEditExtDayCycle::reblendSettings() mWaterBlender->setPosition(position); } -void LLFloaterEditExtDayCycle::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name) -{ - if (mInventoryItem) - { - LLUUID parent_id = mInventoryItem->getParentUUID(); - U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); - LLSettingsVOBase::createInventoryItem(day, next_owner_perm, parent_id, settings_name, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } - else - { - LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - // This method knows what sort of settings object to create. - LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } -} - -void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day) -{ - if (mInventoryId.isNull()) - LLSettingsVOBase::createInventoryItem(day, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - else - LLSettingsVOBase::updateInventoryItem(day, mInventoryId, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); -} - -void LLFloaterEditExtDayCycle::doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day) -{ - U32 flags(0); - - if (mInventoryItem) - { - if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) - flags |= LLSettingsBase::FLAG_NOMOD; - if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) - flags |= LLSettingsBase::FLAG_NOTRANS; - } - - flags |= day->getFlags(); - day->setFlag(flags); - - if (where == ACTION_APPLY_LOCAL) - { - day->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, day); - } - else if (where == ACTION_APPLY_PARCEL) - { - LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); - - if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) - { - LL_WARNS("ENVDAYEDIT") << "Can not identify parcel. Not applying." << LL_ENDL; - LLNotificationsUtil::add("WLParcelApplyFail"); - return; - } - - if (mInventoryItem && !isDirty()) - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); - } - else - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), day, -1, -1); - } - } - else if (where == ACTION_APPLY_REGION) - { - if (mInventoryItem && !isDirty()) - { - LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); - } - else - { - LLEnvironment::instance().updateRegion(day, -1, -1); - } - } - else - { - LL_WARNS("ENVDAYEDIT") << "Unknown apply '" << where << "'" << LL_ENDL; - return; - } - -} - void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day) { if (!mCommitSignal.empty()) @@ -1793,51 +1503,6 @@ bool LLFloaterEditExtDayCycle::isAddingFrameAllowed() return mFramesSlider->canAddSliders(); } -void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) -{ - LL_INFOS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; - - if (inventory_id.isNull() || !results["success"].asBoolean()) - { - LLNotificationsUtil::add("CantCreateInventory"); - return; - } - onInventoryCreated(asset_id, inventory_id); -} - -void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id) -{ - bool can_trans = true; - if (mInventoryItem) - { - LLPermissions perms = mInventoryItem->getPermissions(); - - LLInventoryItem *created_item = gInventory.getItem(mInventoryId); - - if (created_item) - { - can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID()); - created_item->setPermissions(perms); - created_item->updateServer(false); - } - } - - clearDirtyFlag(); - setFocus(TRUE); // Call back the focus... - loadInventoryItem(inventory_id, can_trans); -} - -void LLFloaterEditExtDayCycle::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) -{ - LL_WARNS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; - - clearDirtyFlag(); - if (inventory_id != mInventoryId) - { - loadInventoryItem(inventory_id); - } -} - void LLFloaterEditExtDayCycle::doImportFromDisk() { // Load a a legacy Windlight XML from disk. (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile(); @@ -1864,21 +1529,6 @@ void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vectorsetCursor(UI_CURSOR_WAIT); LLFloaterSettingsPicker *picker = static_cast(mInventoryFloater.get()); // Show the dialog @@ -2003,7 +1647,17 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); }); } + return picker; +} + +void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id) +{ + cloneTrack(track_id, mCurrentTrack); +} +void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem) +{ + LLFloaterSettingsPicker *picker = getSettingsPicker(); picker->setSettingsFilter(type); picker->setSettingsItemId(curritem); if (type == LLSettingsType::ST_DAYCYCLE) @@ -2018,16 +1672,6 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ picker->setFocus(TRUE); } -void LLFloaterEditExtDayCycle::doCloseInventoryFloater(bool quitting) -{ - LLFloater* floaterp = mInventoryFloater.get(); - - if (floaterp) - { - floaterp->closeFloater(quitting); - } -} - void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track) { LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue()); @@ -2118,7 +1762,9 @@ void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID LLInventoryItem *inv_item = gInventory.getItem(item_id); - if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + if (inv_item + && (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()) + || !inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))) { // Need to check if item is already no-transfer, otherwise make it no-transfer bool no_transfer = false; diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h index b6e9fdb14f..8685090d16 100644 --- a/indra/newview/llfloatereditextdaycycle.h +++ b/indra/newview/llfloatereditextdaycycle.h @@ -32,6 +32,7 @@ #include #include "llenvironment.h" +#include "llfloatereditenvironmentbase.h" class LLCheckBoxCtrl; class LLComboBox; @@ -50,14 +51,13 @@ typedef std::shared_ptr LLSettingsBasePtr_t; /** * Floater for creating or editing a day cycle. */ -class LLFloaterEditExtDayCycle : public LLFloater +class LLFloaterEditExtDayCycle : public LLFloaterEditEnvironmentBase { LOG_CLASS(LLFloaterEditExtDayCycle); friend class LLDaySettingCopiedCallback; public: - static const std::string KEY_INVENTORY_ID; static const std::string KEY_EDIT_CONTEXT; static const std::string KEY_DAY_LENGTH; static const std::string KEY_CANMOD; @@ -82,8 +82,8 @@ public: virtual BOOL postBuild() override; virtual void onOpen(const LLSD& key) override; virtual void onClose(bool app_quitting) override; - virtual void onFocusReceived() override; - virtual void onFocusLost() override; + //virtual void onFocusReceived() override; + //virtual void onFocusLost() override; virtual void onVisibilityChange(BOOL new_visibility) override; connection_t setEditCommitSignal(edit_commit_signal_t::slot_type cb); @@ -97,10 +97,13 @@ public: LLUUID getEditingAssetId() { return mEditDay ? mEditDay->getAssetId() : LLUUID::null; } LLUUID getEditingInventoryId() { return mInventoryId; } + virtual LLSettingsBase::ptr_t getEditSettings() const override { return mEditDay; } + BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) override; - BOOL isDirty() const override { return getIsDirty(); } +protected: + virtual void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override; private: typedef std::function on_confirm_fn; @@ -108,8 +111,8 @@ private: // flyout response/click void onButtonApply(LLUICtrl *ctrl, const LLSD &data); - virtual void onClickCloseBtn(bool app_quitting = false) override; - void onButtonImport(); + //virtual void onClickCloseBtn(bool app_quitting = false) override; + //void onButtonImport(); void onButtonLoadFrame(); void onAddFrame(); void onRemoveFrame(); @@ -119,7 +122,6 @@ private: void onCommitName(class LLLineEditor* caller, void* user_data); void onTrackSelectionCallback(const LLSD& user_data); void onPlayActionCallback(const LLSD& user_data); - void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day); // time slider clicked void onTimeSliderCallback(); // a frame moved or frame selection changed @@ -128,10 +130,6 @@ private: void onFrameSliderMouseDown(S32 x, S32 y, MASK mask); void onFrameSliderMouseUp(S32 x, S32 y, MASK mask); - void onPanelDirtyFlagChanged(bool); - - void checkAndConfirmSettingsLoss(on_confirm_fn cb); - void cloneTrack(U32 source_index, U32 dest_index); void cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index); void selectTrack(U32 track_index, bool force = false); @@ -148,25 +146,21 @@ private: void removeCurrentSliderFrame(); void removeSliderFrame(F32 frame); - void loadInventoryItem(const LLUUID &inventoryId, bool can_trans = true); - void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status); - void doImportFromDisk(); void loadSettingFromFile(const std::vector& filenames); - void doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name); - void doApplyUpdateInventory(const LLSettingsDay::ptr_t &day); - void doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day); void doApplyCommit(LLSettingsDay::ptr_t day); void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + void doOpenTrackFloater(const LLSD &args); void doCloseTrackFloater(bool quitting = false); + virtual LLFloaterSettingsPicker* getSettingsPicker() override; void onPickerCommitTrackId(U32 track_id); void doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem); - void doCloseInventoryFloater(bool quitting = false); + //void doCloseInventoryFloater(bool quitting = false); void onPickerCommitSetting(LLUUID item_id, S32 track); void onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, @@ -176,11 +170,7 @@ private: S32 dest_track, LLSettingsBase::TrackPosition dest_frame); - bool canUseInventory() const; - bool canApplyRegion() const; - bool canApplyParcel() const; - - void updateEditEnvironment(); + virtual void updateEditEnvironment() override; void synchronizeTabs(); void reblendSettings(); @@ -193,7 +183,7 @@ private: bool getIsDirty() const { return mIsDirty; } void setDirtyFlag() { mIsDirty = true; } - virtual void clearDirtyFlag(); + virtual void clearDirtyFlag() override; bool isRemovingFrameAllowed(); bool isAddingFrameAllowed(); @@ -218,11 +208,8 @@ private: LLView* mSkyTabLayoutContainer; LLView* mWaterTabLayoutContainer; LLTextBox* mCurrentTimeLabel; - LLUUID mInventoryId; - LLInventoryItem * mInventoryItem; LLFlyoutComboBtnCtrl * mFlyoutControl; - LLHandle mInventoryFloater; LLHandle mTrackFloater; LLTrackBlenderLoopingManual::ptr_t mSkyBlender; @@ -236,11 +223,6 @@ private: LLFrameTimer mPlayTimer; F32 mPlayStartFrame; // an env frame bool mIsPlaying; - bool mIsDirty; - bool mCanCopy; - bool mCanMod; - bool mCanTrans; - bool mCanSave; edit_commit_signal_t mCommitSignal; diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index 37e162b249..41bbd5e8f9 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -81,44 +81,11 @@ namespace const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml"); } -//========================================================================= -const std::string LLFloaterFixedEnvironment::KEY_INVENTORY_ID("inventory_id"); - - -//========================================================================= - -class LLFixedSettingCopiedCallback : public LLInventoryCallback -{ -public: - LLFixedSettingCopiedCallback(LLHandle handle) : mHandle(handle) {} - - virtual void fire(const LLUUID& inv_item_id) - { - if (!mHandle.isDead()) - { - LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); - if (item) - { - LLFloaterFixedEnvironment* floater = (LLFloaterFixedEnvironment*)mHandle.get(); - floater->onInventoryCreated(item->getAssetUUID(), inv_item_id); - } - } - } - -private: - LLHandle mHandle; -}; //========================================================================= LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) : - LLFloater(key), - mFlyoutControl(nullptr), - mInventoryId(), - mInventoryItem(nullptr), - mIsDirty(false), - mCanCopy(false), - mCanMod(false), - mCanTrans(false) + LLFloaterEditEnvironmentBase(key), + mFlyoutControl(nullptr) { } @@ -176,19 +143,6 @@ void LLFloaterFixedEnvironment::onClose(bool app_quitting) syncronizeTabs(); } -void LLFloaterFixedEnvironment::onFocusReceived() -{ - if (isInVisibleChain()) - { - updateEditEnvironment(); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); - } -} - -void LLFloaterFixedEnvironment::onFocusLost() -{ -} - void LLFloaterFixedEnvironment::refresh() { if (!mSettings) @@ -220,6 +174,15 @@ void LLFloaterFixedEnvironment::refresh() } } +void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) +{ + mSettings = settings; // shouldn't this do buildDeepCloneAndUncompress() ? + updateEditEnvironment(); + syncronizeTabs(); + refresh(); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST); +} + void LLFloaterFixedEnvironment::syncronizeTabs() { S32 count = mTab->getTabCount(); @@ -250,131 +213,9 @@ LLFloaterSettingsPicker * LLFloaterFixedEnvironment::getSettingsPicker() return picker; } -void LLFloaterFixedEnvironment::loadInventoryItem(const LLUUID &inventoryId, bool can_trans) -{ - if (inventoryId.isNull()) - { - mInventoryItem = nullptr; - mInventoryId.setNull(); - mCanMod = true; - mCanCopy = true; - mCanTrans = true; - return; - } - - mInventoryId = inventoryId; - LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; - mInventoryItem = gInventory.getItem(mInventoryId); - - if (!mInventoryItem) - { - LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; - LLNotificationsUtil::add("CantFindInvItem"); - closeFloater(); - - mInventoryId.setNull(); - mInventoryItem = nullptr; - return; - } - - if (mInventoryItem->getAssetUUID().isNull()) - { - LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; - LLNotificationsUtil::add("UnableEditItem"); - closeFloater(); - - mInventoryId.setNull(); - mInventoryItem = nullptr; - return; - } - - mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); - mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); - mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); - - LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), - [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - - -void LLFloaterFixedEnvironment::checkAndConfirmSettingsLoss(LLFloaterFixedEnvironment::on_confirm_fn cb) -{ - if (isDirty()) - { - LLSD args(LLSDMap("TYPE", mSettings->getSettingsType()) - ("NAME", mSettings->getName())); - - // create and show confirmation textbox - LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), - [cb](const LLSD¬if, const LLSD&resp) - { - S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); - if (opt == 0) - cb(); - }); - } - else if (cb) - { - cb(); - } -} - void LLFloaterFixedEnvironment::onPickerCommitSetting(LLUUID item_id) { loadInventoryItem(item_id); -// mInventoryId = item_id; -// mInventoryItem = gInventory.getItem(mInventoryId); -// -// mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); -// mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); -// mCanTrans = mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); -// -// LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), -// [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - -void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) -{ - if (mInventoryItem && mInventoryItem->getAssetUUID() != asset_id) - { - LL_WARNS("ENVIRONMENT") << "Discarding obsolete asset callback" << LL_ENDL; - return; - } - - clearDirtyFlag(); - - if (!settings || status) - { - LLSD args; - args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown"; - LLNotificationsUtil::add("FailedToFindSettings", args); - closeFloater(); - return; - } - - mSettings = settings; - if (mInventoryItem) - mSettings->setName(mInventoryItem->getName()); - - if (mCanCopy) - settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); - else - settings->setFlag(LLSettingsBase::FLAG_NOCOPY); - - if (mCanMod) - settings->clearFlag(LLSettingsBase::FLAG_NOMOD); - else - settings->setFlag(LLSettingsBase::FLAG_NOMOD); - - if (mCanTrans) - settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); - else - settings->setFlag(LLSettingsBase::FLAG_NOTRANS); - - updateEditEnvironment(); - syncronizeTabs(); - refresh(); - LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST); } void LLFloaterFixedEnvironment::onNameChanged(const std::string &name) @@ -473,50 +314,6 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) } } -void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) - { - std::string settings_name = response["message"].asString(); - - LLInventoryObject::correctInventoryName(settings_name); - if (settings_name.empty()) - { - // Ideally notification should disable 'OK' button if name won't fit our requirements, - // for now either display notification, or use some default name - settings_name = "Unnamed"; - } - - if (mCanMod) - { - doApplyCreateNewInventory(settings_name, settings); - } - else if (mInventoryItem) - { - const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); - LLUUID parent_id = mInventoryItem->getParentUUID(); - if (marketplacelistings_id == parent_id) - { - parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - } - - LLPointer cb = new LLFixedSettingCopiedCallback(getHandle()); - copy_inventory_item( - gAgent.getID(), - mInventoryItem->getPermissions().getOwner(), - mInventoryItem->getUUID(), - parent_id, - settings_name, - cb); - } - else - { - LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL; - } - } -} - void LLFloaterFixedEnvironment::onClickCloseBtn(bool app_quitting) { if (!app_quitting) @@ -530,116 +327,6 @@ void LLFloaterFixedEnvironment::onButtonLoad() checkAndConfirmSettingsLoss([this](){ doSelectFromInventory(); }); } -void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings) -{ - if (mInventoryItem) - { - LLUUID parent_id = mInventoryItem->getParentUUID(); - U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); - LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } - else - { - LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - // This method knows what sort of settings object to create. - LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } -} - -void LLFloaterFixedEnvironment::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings) -{ - LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL; - if (mInventoryId.isNull()) - { - LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } - else - { - LLSettingsVOBase::updateInventoryItem(settings, mInventoryId, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); - } -} - -void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings) -{ - U32 flags(0); - - if (mInventoryItem) - { - if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) - flags |= LLSettingsBase::FLAG_NOMOD; - if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) - flags |= LLSettingsBase::FLAG_NOTRANS; - } - - flags |= settings->getFlags(); - settings->setFlag(flags); - - if (where == ACTION_APPLY_LOCAL) - { - settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings); - } - else if (where == ACTION_APPLY_PARCEL) - { - LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); - - if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) - { - LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL; - LLNotificationsUtil::add("WLParcelApplyFail"); - return; - } - - if (mInventoryItem && !isDirty()) - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); - } - else if (settings->getSettingsType() == "sky") - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); - } - else if (settings->getSettingsType() == "water") - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); - } - } - else if (where == ACTION_APPLY_REGION) - { - if (mInventoryItem && !isDirty()) - { - LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); - } - else if (settings->getSettingsType() == "sky") - { - LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); - } - else if (settings->getSettingsType() == "water") - { - LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); - } - } - else - { - LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; - return; - } - -} - -void LLFloaterFixedEnvironment::doCloseInventoryFloater(bool quitting) -{ - LLFloater* floaterp = mInventoryFloater.get(); - - if (floaterp) - { - floaterp->closeFloater(quitting); - } -} - void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) { LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; @@ -709,28 +396,6 @@ void LLFloaterFixedEnvironment::doSelectFromInventory() picker->setFocus(TRUE); } -void LLFloaterFixedEnvironment::onPanelDirtyFlagChanged(bool value) -{ - if (value) - setDirtyFlag(); -} - -//------------------------------------------------------------------------- -bool LLFloaterFixedEnvironment::canUseInventory() const -{ - return LLEnvironment::instance().isInventoryEnabled(); -} - -bool LLFloaterFixedEnvironment::canApplyRegion() const -{ - return gAgent.canManageEstate(); -} - -bool LLFloaterFixedEnvironment::canApplyParcel() const -{ - return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); -} - //========================================================================= LLFloaterFixedEnvironmentWater::LLFloaterFixedEnvironmentWater(const LLSD &key): LLFloaterFixedEnvironment(key) diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h index 513996c4a3..1620bc101a 100644 --- a/indra/newview/llfloaterfixedenvironment.h +++ b/indra/newview/llfloaterfixedenvironment.h @@ -27,7 +27,7 @@ #ifndef LL_FLOATERFIXEDENVIRONMENT_H #define LL_FLOATERFIXEDENVIRONMENT_H -#include "llfloater.h" +#include "llfloatereditenvironmentbase.h" #include "llsettingsbase.h" #include "llflyoutcombobtn.h" #include "llinventory.h" @@ -43,15 +43,10 @@ class LLFixedSettingCopiedCallback; /** * Floater container for creating and editing fixed environment settings. */ -class LLFloaterFixedEnvironment : public LLFloater +class LLFloaterFixedEnvironment : public LLFloaterEditEnvironmentBase { LOG_CLASS(LLFloaterFixedEnvironment); - - friend class LLFixedSettingCopiedCallback; - public: - static const std::string KEY_INVENTORY_ID; - LLFloaterFixedEnvironment(const LLSD &key); ~LLFloaterFixedEnvironment(); @@ -59,26 +54,17 @@ public: virtual void onOpen(const LLSD& key) override; virtual void onClose(bool app_quitting) override; - virtual void onFocusReceived() override; - virtual void onFocusLost() override; - void setEditSettings(const LLSettingsBase::ptr_t &settings) { mSettings = settings; clearDirtyFlag(); syncronizeTabs(); refresh(); } - LLSettingsBase::ptr_t getEditSettings() const { return mSettings; } - - virtual BOOL isDirty() const override { return getIsDirty(); } + virtual LLSettingsBase::ptr_t getEditSettings() const override { return mSettings; } protected: typedef std::function on_confirm_fn; - virtual void updateEditEnvironment() = 0; virtual void refresh() override; + void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override; virtual void syncronizeTabs(); - LLFloaterSettingsPicker *getSettingsPicker(); - - void loadInventoryItem(const LLUUID &inventoryId, bool can_trans = true); - - void checkAndConfirmSettingsLoss(on_confirm_fn cb); + virtual LLFloaterSettingsPicker *getSettingsPicker() override; LLTabContainer * mTab; LLLineEditor * mTxtName; @@ -86,24 +72,9 @@ protected: LLSettingsBase::ptr_t mSettings; virtual void doImportFromDisk() = 0; - virtual void doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings); - virtual void doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings); - virtual void doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings); - void doCloseInventoryFloater(bool quitting = false); - - bool canUseInventory() const; - bool canApplyRegion() const; - bool canApplyParcel() const; LLFlyoutComboBtnCtrl * mFlyoutControl; - LLUUID mInventoryId; - LLInventoryItem * mInventoryItem; - LLHandle mInventoryFloater; - bool mCanCopy; - bool mCanMod; - bool mCanTrans; - void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); @@ -113,10 +84,8 @@ protected: virtual void clearDirtyFlag(); void doSelectFromInventory(); - void onPanelDirtyFlagChanged(bool); virtual void onClickCloseBtn(bool app_quitting = false) override; - void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings); private: void onNameChanged(const std::string &name); @@ -126,9 +95,6 @@ private: void onButtonLoad(); void onPickerCommitSetting(LLUUID item_id); - void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status); - - bool mIsDirty; }; class LLFloaterFixedEnvironmentWater : public LLFloaterFixedEnvironment @@ -172,36 +138,4 @@ protected: private: }; -class LLSettingsEditPanel : public LLPanel -{ -public: - virtual void setSettings(const LLSettingsBase::ptr_t &) = 0; - - typedef boost::signals2::signal on_dirty_charged_sg; - typedef boost::signals2::connection connection_t; - - inline bool getIsDirty() const { return mIsDirty; } - inline void setIsDirty() { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } - inline void clearIsDirty() { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } - - inline bool getCanChangeSettings() const { return mCanEdit; } - inline void setCanChangeSettings(bool flag) { mCanEdit = flag; } - - inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb) { return mOnDirtyChanged.connect(cb); } - - -protected: - LLSettingsEditPanel() : - LLPanel(), - mIsDirty(false), - mOnDirtyChanged() - {} - -private: - bool mIsDirty; - bool mCanEdit; - - on_dirty_charged_sg mOnDirtyChanged; -}; - #endif // LL_FLOATERFIXEDENVIRONMENT_H diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h index c02c9c95a0..801fb8b9b2 100644 --- a/indra/newview/llpaneleditsky.h +++ b/indra/newview/llpaneleditsky.h @@ -29,7 +29,7 @@ #include "llpanel.h" #include "llsettingssky.h" -#include "llfloaterfixedenvironment.h" +#include "llfloatereditenvironmentbase.h" //========================================================================= class LLSlider; diff --git a/indra/newview/llpaneleditwater.h b/indra/newview/llpaneleditwater.h index ab2dc47bcc..4b7ec903c9 100644 --- a/indra/newview/llpaneleditwater.h +++ b/indra/newview/llpaneleditwater.h @@ -30,7 +30,7 @@ #include "llpanel.h" #include "llsettingswater.h" -#include "llfloaterfixedenvironment.h" +#include "llfloatereditenvironmentbase.h" //========================================================================= class LLSlider; -- cgit v1.2.3 From efee1d96372e3d13c29943728ec4249d5e71895c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jul 2020 20:35:52 +0300 Subject: SL-13516 MAC build fix --- indra/newview/llfloatereditextdaycycle.h | 2 +- indra/newview/llfloaterfixedenvironment.h | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h index 8685090d16..9a30fb199f 100644 --- a/indra/newview/llfloatereditextdaycycle.h +++ b/indra/newview/llfloatereditextdaycycle.h @@ -146,7 +146,7 @@ private: void removeCurrentSliderFrame(); void removeSliderFrame(F32 frame); - void doImportFromDisk(); + virtual void doImportFromDisk() override; void loadSettingFromFile(const std::vector& filenames); void doApplyCommit(LLSettingsDay::ptr_t day); void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h index 1620bc101a..00b6c3a570 100644 --- a/indra/newview/llfloaterfixedenvironment.h +++ b/indra/newview/llfloaterfixedenvironment.h @@ -79,9 +79,8 @@ protected: void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); - bool getIsDirty() const { return mIsDirty; } - void setDirtyFlag() { mIsDirty = true; } - virtual void clearDirtyFlag(); + virtual void clearDirtyFlag() override; + void updatePermissionFlags(); void doSelectFromInventory(); -- cgit v1.2.3 From 6c17533dddf2d93ead2272c6a6ba588c5ab7e769 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jul 2020 21:46:57 +0300 Subject: SL-13516 MAC build fix 2 --- indra/newview/llfloaterfixedenvironment.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h index 00b6c3a570..f35f4a4368 100644 --- a/indra/newview/llfloaterfixedenvironment.h +++ b/indra/newview/llfloaterfixedenvironment.h @@ -71,8 +71,6 @@ protected: LLSettingsBase::ptr_t mSettings; - virtual void doImportFromDisk() = 0; - LLFlyoutComboBtnCtrl * mFlyoutControl; void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); -- cgit v1.2.3 From 358b65198a8d17067eddc1bb02d6363000b3699b Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 21 Jul 2020 16:55:09 +0300 Subject: SL-13628 FIXED Object's name and description are not populated when cycling through faces --- indra/newview/llviewermenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b6c7be2ed3..0b44e50dd6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -5353,7 +5353,7 @@ class LLToolsSelectNextPartFace : public view_listener_t new_te = to_select->getNumTEs() - 1; } } - LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, FALSE); + LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te); } else { -- cgit v1.2.3 From 7d4b1c014c9900af47005a529df50ece14249326 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 22 Jul 2020 14:41:19 +0300 Subject: SL-13082 Declare macOS SDK version to be 10.12 instead of 10.15 --- indra/newview/CMakeLists.txt | 4 ++++ indra/newview/Info-SecondLife.plist | 2 ++ 2 files changed, 6 insertions(+) (limited to 'indra') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 0d204fd716..a17bf088cd 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1944,6 +1944,10 @@ elseif (DARWIN) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP" + # Force the SDK version in the linked executable to be 10.12. This will fool + # macOS into using the pre-Mojave display system, avoiding the blurry display that + # otherwise occurs when upscaling the viewer to Retina resolution levels. + LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -platform_version -Xlinker macos -Xlinker ${CMAKE_OSX_DEPLOYMENT_TARGET} -Xlinker 10.12" ) else (WINDOWS) # Linux diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index cfe9d991c5..4f09495f83 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -79,5 +79,7 @@ ${MACOSX_BUNDLE_NSPRINCIPAL_CLASS} NSMainNibFile ${MACOSX_BUNDLE_NSMAIN_NIB_FILE} + NSHighResolutionCapable + -- cgit v1.2.3 From 48a4e9f5ed3851bd56bd54c5c761fe9133b92350 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 22 Jul 2020 19:15:28 +0300 Subject: SL-13620 FIXED The code appears instead of the maturity icon in the chat history --- indra/newview/llimprocessing.cpp | 18 +++++++++--------- indra/newview/llnotificationhandler.h | 1 + indra/newview/llnotificationhandlerutil.cpp | 15 ++++++++++----- indra/newview/llnotificationofferhandler.cpp | 16 +++++++++++++++- 4 files changed, 35 insertions(+), 15 deletions(-) (limited to 'indra') diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 7b87b43243..6ccb9766a5 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1606,15 +1606,15 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) bin_bucket.push_back(0); } - // Todo: once drtsim-451 releases, remove the string option - BOOL from_group; - if (message_data["from_group"].isInteger()) - { - from_group = message_data["from_group"].asInteger(); - } - else - { - from_group = message_data["from_group"].asString() == "Y"; + // Todo: once drtsim-451 releases, remove the string option + BOOL from_group; + if (message_data["from_group"].isInteger()) + { + from_group = message_data["from_group"].asInteger(); + } + else + { + from_group = message_data["from_group"].asString() == "Y"; } LLIMProcessing::processNewMessage( diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 52c5234137..ef4aced2c7 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -297,6 +297,7 @@ public: * Writes notification message to IM p2p session. */ static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false); + static void logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only = false); /** * Writes group notice notification message to IM group session. diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 9a3f1a853a..39a0b9b50e 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -123,15 +123,13 @@ void log_name_callback(const LLAvatarName& av_name, const std::string& from_name } // static -void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) +void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only) { if (!gCacheName) { return; } - LLUUID from_id = notification->getPayload()["from_id"]; - if (from_id.isNull()) { // Normal behavior for system generated messages, don't spam. @@ -141,14 +139,21 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi if(to_file_only) { - LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID())); + LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", message, LLUUID())); } else { - LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id)); + LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, message, from_id)); } } +// static +void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) +{ + LLUUID from_id = notification->getPayload()["from_id"]; + logToIMP2P(from_id, notification->getMessage(), to_file_only); +} + // static void LLHandlerUtil::logGroupNoticeToIMGroup( const LLNotificationPtr& notification) diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 14d25d8158..a9678b1e93 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -37,6 +37,8 @@ #include "llimview.h" #include "llnotificationsutil.h" +#include + using namespace LLNotificationsUI; //-------------------------------------------------------------------------- @@ -143,7 +145,19 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) { // log only to file if notif panel can be embedded to IM and IM is opened bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification); - LLHandlerUtil::logToIMP2P(notification, file_only); + if ((notification->getName() == "TeleportOffered" + || notification->getName() == "TeleportOffered_MaturityExceeded" + || notification->getName() == "TeleportOffered_MaturityBlocked")) + { + boost::regex r("\\s*([^<]*)?\\s*( - )?", + boost::regex::perl|boost::regex::icase); + std::string stripped_msg = boost::regex_replace(notification->getMessage(), r, ""); + LLHandlerUtil::logToIMP2P(notification->getPayload()["from_id"], stripped_msg,file_only); + } + else + { + LLHandlerUtil::logToIMP2P(notification, file_only); + } } } -- cgit v1.2.3 From fe910b64a0f245fed7354c69da1d9787072e5405 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 23 Jul 2020 20:52:41 +0300 Subject: SL-13513 Tree's trunk should decrease quality at higher distance --- indra/newview/llvotree.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 8e46ccd555..41099cb570 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -45,6 +45,8 @@ #include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" +#include "llvolumemgr.h" +#include "llvovolume.h" #include "llworld.h" #include "noise.h" #include "pipeline.h" @@ -85,6 +87,9 @@ LLVOTree::LLVOTree(const LLUUID &id, const LLPCode pcode, LLViewerRegion *region mFrameCount = 0; mWind = mRegionp->mWind.getVelocity(getPositionRegion()); mTrunkLOD = 0; + + // if assert triggers, idleUpdate() needs to be revised and adjusted to new LOD levels + llassert(sMAX_NUM_TREE_LOD_LEVELS == LLVolumeLODGroup::NUM_LODS); } @@ -347,8 +352,11 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time) return; } - S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; + S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; // disabled F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; + F32 distance = mDrawable->mDistanceWRTCamera * LLVOVolume::sDistanceFactor * (F_PI / 3.f); + F32 diameter = getScale().length(); // trees have very broken scale, but length rougtly outlines proper diameter + F32 sz = mBillboardScale * mBillboardRatio * diameter; for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++) { @@ -357,7 +365,14 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time) trunk_LOD = j; break; } - } + } + + F32 tan_angle = (LLVOTree::sTreeFactor * 64 * sz) / distance; + S32 cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); // larger value, better quality + + // for trunk_LOD lower value means better quality, but both trunk_LOD and cur_detail have 4 levels + trunk_LOD = llmax(trunk_LOD, LLVolumeLODGroup::NUM_LODS - cur_detail - 1); + trunk_LOD = llmin(trunk_LOD, sMAX_NUM_TREE_LOD_LEVELS); if (mReferenceBuffer.isNull()) { @@ -408,8 +423,9 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent) LLVector3 lookAt = center - viewer_pos_agent; F32 dist = lookAt.normVec() ; F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; - - F32 range = dist - getMinScale()/2; + F32 radius = getScale().length()*0.5f; + F32 range = dist - radius; + if (range < F_ALMOST_ZERO || isHUDAttachment()) // range == zero { mAppAngle = 180.f; -- cgit v1.2.3 From 03a33bf07541f4555c840e2323e9e68fadc72689 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 29 Jul 2020 12:37:07 +0300 Subject: SL-13695 update chat message string with instructions --- indra/newview/skins/default/xui/en/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 1bfac6aeb7..29eb733d41 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3691,10 +3691,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Also there are some other places where "generic" is used. So, let add string with name="generic" with the same value as "generic_request_error" --> - Error making request, please try again later. + Please close and reopen the conversation, or relog and try again. - Error making request, please try again later. + Please close and reopen the conversation, or relog and try again. You do not have sufficient permissions. -- cgit v1.2.3 From cc25193af9a64f36a75f401160f5757498f3e5fc Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 1 Aug 2020 01:19:10 +0300 Subject: SL-12795 Fix existance of multiple chatlog files after name change --- indra/newview/llconversationlog.cpp | 17 +++++++++++++++++ indra/newview/llconversationlog.h | 6 +++++- indra/newview/llimview.cpp | 4 ++++ indra/newview/lllogchat.cpp | 22 ++++++++++++++++++++++ indra/newview/lllogchat.h | 1 + 5 files changed, 49 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index 5539fa75dd..dcffaf5930 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -398,6 +398,23 @@ void LLConversationLog::deleteBackupLogs() } } +void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::string &expected_filename) +{ + conversations_vec_t::iterator conv_it = mConversations.begin(); + for (; conv_it != mConversations.end(); ++conv_it) + { + if (conv_it->getSessionID() == session_id) + { + if (conv_it->getHistoryFileName() != expected_filename) + { + LLLogChat::renameLogFile(conv_it->getHistoryFileName(), expected_filename); + conv_it->updateHistoryFileName(expected_filename); + } + break; + } + } +} + bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory) { diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index 46e46a3278..82e7e597d0 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -59,7 +59,7 @@ public: getTime() const { return mTime; } bool hasOfflineMessages() const { return mHasOfflineIMs; } - void setConversationName(std::string conv_name) { mConversationName = conv_name; } + void setConversationName(const std::string &conv_name) { mConversationName = conv_name; } void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; } bool isOlderThan(U32Days days) const; @@ -68,6 +68,8 @@ public: */ void updateTimestamp(); + void updateHistoryFileName(const std::string &new_name) { mHistoryFileName = new_name; } + /* * Resets flag of unread offline message to false when im floater with this conversation is opened. */ @@ -137,6 +139,8 @@ public: * public method which is called on viewer exit to save conversation log */ void cache(); + // will check if current name is edentical with the one on disk and will rename the one on disk if it isn't + void verifyFilename(const LLUUID& session_id, const std::string &expected_filename); bool moveLog(const std::string &originDirectory, const std::string &targetDirectory); void getListOfBackupLogs(std::vector& list_of_backup_logs); void deleteBackupLogs(); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index d5142a4496..72162a1242 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -601,6 +601,10 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& } buildHistoryFileName(); + if (isP2P()) // user's account name can change, but filenames are account name based + { + LLConversationLog::getInstance()->verifyFilename(mSessionID, mHistoryFileName); + } loadHistory(); // Localizing name of ad-hoc session. STORM-153 diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 0c64531783..abd7102aea 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -271,6 +271,28 @@ std::string LLLogChat::makeLogFileName(std::string filename) return filename; } +//static +void LLLogChat::renameLogFile(const std::string& old_filename, const std::string& new_filename) +{ + std::string new_name = cleanFileName(new_filename); + std::string old_name = cleanFileName(old_filename); + new_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, new_name); + old_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, old_name); + + if (new_name.empty() || old_name.empty()) + { + return; + } + + new_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION; + old_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION; + + if (!LLFile::isfile(new_name) && LLFile::isfile(old_name)) + { + LLFile::rename(old_name, new_name); + } +} + std::string LLLogChat::cleanFileName(std::string filename) { std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 8b7fe14e16..c4b61ee716 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -94,6 +94,7 @@ public: static std::string timestamp(bool withdate = false); static std::string makeLogFileName(std::string(filename)); + static void renameLogFile(const std::string& old_filename, const std::string& new_filename); /** *Add functions to get old and non date stamped file names when needed */ -- cgit v1.2.3 From 6afefa31df7947ad5d1c35d4d2d564a6521ff0f5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 3 Aug 2020 20:55:36 +0300 Subject: SL-13691 wstring index was used for normal string --- indra/newview/llpreviewscript.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 7a68d1e270..9a79ab2fd1 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -736,7 +736,10 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) } if (immediate || (mLiveHelpTimer.getStarted() && mLiveHelpTimer.getElapsedTimeF32() > LIVE_HELP_REFRESH_TIME)) { - std::string help_string = mEditor->getText().substr(segment->getStart(), segment->getEnd() - segment->getStart()); + // Use Wtext since segment's start/end are made for wstring and will + // result in a shift for case of multi-byte symbols inside std::string. + LLWString segment_text = mEditor->getWText().substr(segment->getStart(), segment->getEnd() - segment->getStart()); + std::string help_string = wstring_to_utf8str(segment_text); setHelpPage(help_string); mLiveHelpTimer.stop(); } -- cgit v1.2.3 From 6077f296dd7c23b188dd4813636f7b2b83658b96 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 5 Aug 2020 13:16:38 +0300 Subject: SL-13714 FIXED Buy floater allows multiple buy --- indra/newview/llfloaterbuy.cpp | 39 +++++++++++++++++++++- indra/newview/llfloaterbuy.h | 5 +++ .../skins/default/xui/en/floater_buy_object.xml | 4 +++ 3 files changed, 47 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 4d3ebcda1e..ea93d3bfaa 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -49,7 +49,8 @@ #include "lltrans.h" LLFloaterBuy::LLFloaterBuy(const LLSD& key) -: LLFloater(key) +: LLFloater(key), + mSelectionUpdateSlot() { } @@ -179,12 +180,19 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) floater->getChild("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice())); floater->getChild("buy_name_text")->setTextArg("[NAME]", owner_name); + floater->showViews(true); + // Must do this after the floater is created, because // sometimes the inventory is already there and // the callback is called immediately. LLViewerObject* obj = selection->getFirstRootObject(); floater->registerVOInventoryListener(obj,NULL); floater->requestVOInventory(); + + if (!floater->mSelectionUpdateSlot.connected()) + { + floater->mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterBuy::onSelectionChanged, floater)); + } } void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, @@ -280,6 +288,30 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, removeVOInventoryListener(); } +void LLFloaterBuy::onSelectionChanged() +{ + + if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() == 0) + { + removeVOInventoryListener(); + closeFloater(); + } + else if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() > 1) + { + removeVOInventoryListener(); + showViews(false); + reset(); + setTitle(getString("mupliple_selected")); + } +} + +void LLFloaterBuy::showViews(bool show) +{ + getChild("buy_btn")->setEnabled(show); + getChild("buy_text")->setVisible(show); + getChild("buy_name_text")->setVisible(show); +} + void LLFloaterBuy::onClickBuy() { // Put the items where we put new folders. @@ -303,5 +335,10 @@ void LLFloaterBuy::onClickCancel() // virtual void LLFloaterBuy::onClose(bool app_quitting) { + if (mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot.disconnect(); + } + mObjectSelection.clear(); } diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h index 3ec642dee1..e83b3c6ba6 100644 --- a/indra/newview/llfloaterbuy.h +++ b/indra/newview/llfloaterbuy.h @@ -63,12 +63,17 @@ protected: S32 serial_num, void* data); + void onSelectionChanged(); + void showViews(bool show); + void onClickBuy(); void onClickCancel(); private: LLSafeHandle mObjectSelection; LLSaleInfo mSaleInfo; + + boost::signals2::connection mSelectionUpdateSlot; }; #endif diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml index 49be4290c7..1f7d52dbf5 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml @@ -32,6 +32,10 @@ name="no_transfer_text"> (no transfer) + + Mupliple selection + Date: Thu, 6 Aug 2020 15:23:12 +0300 Subject: Revert "SL-13082 Declare macOS SDK version to be 10.12 instead of 10.15" This reverts commit 7d4b1c014c9900af47005a529df50ece14249326. Until the TC mac build nodes update. --- indra/newview/CMakeLists.txt | 4 ---- indra/newview/Info-SecondLife.plist | 2 -- 2 files changed, 6 deletions(-) (limited to 'indra') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a17bf088cd..0d204fd716 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1944,10 +1944,6 @@ elseif (DARWIN) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP" - # Force the SDK version in the linked executable to be 10.12. This will fool - # macOS into using the pre-Mojave display system, avoiding the blurry display that - # otherwise occurs when upscaling the viewer to Retina resolution levels. - LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -platform_version -Xlinker macos -Xlinker ${CMAKE_OSX_DEPLOYMENT_TARGET} -Xlinker 10.12" ) else (WINDOWS) # Linux diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 4f09495f83..cfe9d991c5 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -79,7 +79,5 @@ ${MACOSX_BUNDLE_NSPRINCIPAL_CLASS} NSMainNibFile ${MACOSX_BUNDLE_NSMAIN_NIB_FILE} - NSHighResolutionCapable - -- cgit v1.2.3 From ba04feea1f2918fa064a6168a72cb11b01617732 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 10 Aug 2020 12:11:14 +0300 Subject: SL-13618 FIXED uri's stuck showing "Loading..." in chat or dialog if more than one name is not cached. --- indra/llui/llurlentry.cpp | 50 +++++++++++++++++++++++++++++++++++------------ indra/llui/llurlentry.h | 24 +++++++++++++++++------ 2 files changed, 56 insertions(+), 18 deletions(-) (limited to 'indra') diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 333d03f208..d8d46e9e62 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -511,8 +511,7 @@ LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL() // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about // -LLUrlEntryAgent::LLUrlEntryAgent() : - mAvatarNameCacheConnection() +LLUrlEntryAgent::LLUrlEntryAgent() { mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+", boost::regex::perl|boost::regex::icase); @@ -543,7 +542,15 @@ void LLUrlEntryAgent::callObservers(const std::string &id, void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name) { - mAvatarNameCacheConnection.disconnect(); + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } std::string label = av_name.getCompleteName(); @@ -630,11 +637,17 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa } else { - if (mAvatarNameCacheConnection.connected()) + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); + if (it != mAvatarNameCacheConnections.end()) { - mAvatarNameCacheConnection.disconnect(); + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); } - mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2)); + mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2)); + addObserver(agent_id_string, url, cb); return LLTrans::getString("LoadingData"); } @@ -695,14 +708,21 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url) // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) // -LLUrlEntryAgentName::LLUrlEntryAgentName() : - mAvatarNameCacheConnection() +LLUrlEntryAgentName::LLUrlEntryAgentName() {} void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name) { - mAvatarNameCacheConnection.disconnect(); + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } std::string label = getName(av_name); // received the agent name from the server - tell our observers @@ -737,11 +757,17 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab } else { - if (mAvatarNameCacheConnection.connected()) + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); + if (it != mAvatarNameCacheConnections.end()) { - mAvatarNameCacheConnection.disconnect(); + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); } - mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2)); + mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2)); + addObserver(agent_id_string, url, cb); return LLTrans::getString("LoadingData"); } diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 78c149d9fd..61aa94a813 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -212,10 +212,14 @@ public: LLUrlEntryAgent(); ~LLUrlEntryAgent() { - if (mAvatarNameCacheConnection.connected()) + for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) { - mAvatarNameCacheConnection.disconnect(); + if (it->second.connected()) + { + it->second.disconnect(); + } } + mAvatarNameCacheConnections.clear(); } /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getIcon(const std::string &url); @@ -227,7 +231,9 @@ protected: /*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon); private: void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); - boost::signals2::connection mAvatarNameCacheConnection; + + typedef std::map avatar_name_cache_connection_map_t; + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; }; /// @@ -241,10 +247,14 @@ public: LLUrlEntryAgentName(); ~LLUrlEntryAgentName() { - if (mAvatarNameCacheConnection.connected()) + for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) { - mAvatarNameCacheConnection.disconnect(); + if (it->second.connected()) + { + it->second.disconnect(); + } } + mAvatarNameCacheConnections.clear(); } /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ LLStyle::Params getStyle() const; @@ -253,7 +263,9 @@ protected: virtual std::string getName(const LLAvatarName& avatar_name) = 0; private: void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); - boost::signals2::connection mAvatarNameCacheConnection; + + typedef std::map avatar_name_cache_connection_map_t; + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; }; -- cgit v1.2.3 From 0c9e8dddc80afbf45e8b8027d048857456d44b9b Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 11 Aug 2020 20:50:57 +0300 Subject: SL-13731 FIXED Issue with selecting custom preset while in 'Object view' mode --- indra/newview/llfloatercamera.cpp | 19 ++----------------- indra/newview/llfloatercamera.h | 4 ---- 2 files changed, 2 insertions(+), 21 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index d574f1433f..3b192ff81b 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -457,6 +457,7 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode) switch (mode) { + case CAMERA_CTRL_MODE_PRESETS: case CAMERA_CTRL_MODE_PAN: sFreeCamera = false; clear_camera_tool(); @@ -467,13 +468,6 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode) activate_camera_tool(); break; - case CAMERA_CTRL_MODE_PRESETS: - if(sFreeCamera) - { - switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); - } - break; - default: //normally we won't occur here llassert_always(FALSE); @@ -528,7 +522,6 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param) { camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); camera_floater->updateItemsSelection(); - camera_floater->fromFreeToPresets(); } } else @@ -586,15 +579,7 @@ void LLFloaterCamera::switchToPreset(const std::string& name) if (camera_floater) { camera_floater->updateItemsSelection(); - camera_floater->fromFreeToPresets(); - } -} - -void LLFloaterCamera::fromFreeToPresets() -{ - if (!sFreeCamera && mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && mPrevMode == CAMERA_CTRL_MODE_PRESETS) - { - switchMode(CAMERA_CTRL_MODE_PRESETS); + camera_floater->switchMode(CAMERA_CTRL_MODE_PRESETS); } } diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index 9440f50c3f..a69b87ad16 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -69,10 +69,6 @@ public: /*switch to one of the camera presets (front, rear, side)*/ static void switchToPreset(const std::string& name); - /* move to CAMERA_CTRL_MODE_PRESETS from CAMERA_CTRL_MODE_FREE_CAMERA if we are on presets panel and - are not in free camera mode*/ - void fromFreeToPresets(); - virtual void onOpen(const LLSD& key); virtual void onClose(bool app_quitting); -- cgit v1.2.3 From a62a0fc62ce961dd570eefbe37eda51e50310df6 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 13 Aug 2020 19:47:09 +0300 Subject: SL-13149 FIXED URLs copied from MoaP have 6 space characters at the beginning --- indra/newview/llpanelprimmediacontrols.cpp | 10 +++++++--- indra/newview/llpanelprimmediacontrols.h | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 55c84815aa..6bb213c0ef 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -73,6 +73,8 @@ bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model); const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM }; const int LLPanelPrimMediaControls::kNumZoomLevels = 2; +const S32 ADDR_LEFT_PAD = 3; + // // LLPanelPrimMediaControls // @@ -154,7 +156,7 @@ BOOL LLPanelPrimMediaControls::postBuild() mMediaProgressPanel = getChild("media_progress_indicator"); mMediaProgressBar = getChild("media_progress_bar"); mMediaAddressCtrl = getChild("media_address"); - mMediaAddress = getChild("media_address_url"); + mMediaAddress = getChild("media_address_url"); mMediaPlaySliderPanel = getChild("media_play_position"); mMediaPlaySliderCtrl = getChild("media_play_slider"); mSkipFwdCtrl = getChild("skip_forward"); @@ -498,8 +500,10 @@ void LLPanelPrimMediaControls::updateShape() std::string test_prefix = mCurrentURL.substr(0, prefix.length()); LLStringUtil::toLower(test_prefix); mSecureURL = has_focus && (test_prefix == prefix); - mCurrentURL = (mSecureURL ? " " + mCurrentURL : mCurrentURL); - + + S32 left_pad = mSecureURL ? mSecureLockIcon->getRect().getWidth() : ADDR_LEFT_PAD; + mMediaAddress->setTextPadding(left_pad, 0); + if(mCurrentURL!=mPreviousURL) { setCurrentURL(); diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index d4301aaf7c..a8d0e31cf2 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -39,6 +39,7 @@ class LLProgressBar; class LLSliderCtrl; class LLViewerMediaImpl; class LLWindowShade; +class LLLineEditor; class LLPanelPrimMediaControls : public LLPanel { @@ -162,7 +163,7 @@ private: LLPanel *mMediaProgressPanel; LLProgressBar *mMediaProgressBar; LLUICtrl *mMediaAddressCtrl; - LLUICtrl *mMediaAddress; + LLLineEditor *mMediaAddress; LLUICtrl *mMediaPlaySliderPanel; LLUICtrl *mMediaPlaySliderCtrl; LLUICtrl *mVolumeCtrl; -- cgit v1.2.3 From e67e9f63c30555467ac6a381e229e45150fb2509 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 14 Aug 2020 01:06:48 +0300 Subject: SL-13293 Fixed reshape behavior for scale change --- indra/llui/llcheckboxctrl.cpp | 30 +++++++++++++++++++++++++++--- indra/llui/lllayoutstack.cpp | 2 +- indra/llui/lltextbase.cpp | 2 +- indra/llui/lltextbox.cpp | 4 ++-- indra/llui/lltextbox.h | 2 +- indra/llui/llview.cpp | 4 +++- indra/newview/llpanellogin.cpp | 10 ++++++++++ indra/newview/llpanellogin.h | 1 + indra/newview/llviewerwindow.cpp | 5 +++++ 9 files changed, 51 insertions(+), 9 deletions(-) (limited to 'indra') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 6a51c4240b..08da599ef2 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -187,10 +187,32 @@ void LLCheckBoxCtrl::clear() void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) { - S32 label_top = mLabel->getRect().mTop; - mLabel->reshapeToFitText(); + LLRect rect = getRect(); + S32 delta_width = width - rect.getWidth(); + S32 delta_height = height - rect.getHeight(); - LLRect label_rect = mLabel->getRect(); + if (delta_width || delta_height) + { + // adjust our rectangle + rect.mRight = getRect().mLeft + width; + rect.mTop = getRect().mBottom + height; + setRect(rect); + } + + // reshapeToFitText reshapes label to minimal size according to last bounding box + // it will work fine in case of decrease of space, but if we get more space or text + // becomes longer, label will fail to grow so reinit label's dimentions. + + static LLUICachedControl llcheckboxctrl_hpad("UICheckboxctrlHPad", 0); + LLRect label_rect = mLabel->getRect(); + S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad; + label_rect.mRight = label_rect.mLeft + new_width; + mLabel->setRect(label_rect); + + S32 label_top = label_rect.mTop; + mLabel->reshapeToFitText(TRUE); + + label_rect = mLabel->getRect(); if (label_top != label_rect.mTop && mWordWrap == WRAP_DOWN) { // reshapeToFitText uses LLView::reshape() which always reshapes @@ -210,6 +232,8 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft), llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight())); mButton->setShape(btn_rect); + + updateBoundingRect(); } //virtual diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 4aae1e374b..29a156e933 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -166,7 +166,7 @@ void LLLayoutPanel::setVisible( BOOL visible ) void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ ) { - if (width == getRect().getWidth() && height == getRect().getHeight()) return; + if (width == getRect().getWidth() && height == getRect().getHeight() && !LLView::sForceReshape) return; if (!mIgnoreReshape && mAutoResize == false) { diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 83b851eed2..fc1301351d 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1148,7 +1148,7 @@ BOOL LLTextBase::handleToolTip(S32 x, S32 y, MASK mask) void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent) { - if (width != getRect().getWidth() || height != getRect().getHeight()) + if (width != getRect().getWidth() || height != getRect().getHeight() || LLView::sForceReshape) { bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 0afd32f332..134afc005b 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -163,13 +163,13 @@ BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text } -void LLTextBox::reshapeToFitText() +void LLTextBox::reshapeToFitText(BOOL called_from_parent) { reflow(); S32 width = getTextPixelWidth(); S32 height = getTextPixelHeight(); - reshape( width + 2 * mHPad, height + 2 * mVPad, FALSE ); + reshape( width + 2 * mHPad, height + 2 * mVPad, called_from_parent ); } diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 061d2dd23d..c3e3b61912 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -60,7 +60,7 @@ public: void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } void setClickedCallback( boost::function cb, void* userdata = NULL ); - void reshapeToFitText(); + void reshapeToFitText(BOOL called_from_parent = FALSE); S32 getTextPixelWidth(); S32 getTextPixelHeight(); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 593c8b12fc..4a990cea81 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1387,7 +1387,9 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft; S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom; viewp->translate( delta_x, delta_y ); - if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight()) + if (child_rect.getWidth() != viewp->getRect().getWidth() + || child_rect.getHeight() != viewp->getRect().getHeight() + || sForceReshape) { viewp->reshape(child_rect.getWidth(), child_rect.getHeight()); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 70757882d8..849b75773d 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -541,6 +541,16 @@ void LLPanelLogin::show(const LLRect &rect, gFocusMgr.setDefaultKeyboardFocus(sInstance); } +//static +void LLPanelLogin::reshapePanel() +{ + if (sInstance) + { + LLRect rect = sInstance->getRect(); + sInstance->reshape(rect.getWidth(), rect.getHeight()); + } +} + //static void LLPanelLogin::populateFields(LLPointer credential, bool remember_user, bool remember_psswrd) { diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index c9b8e1b6fc..788c269ffd 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -54,6 +54,7 @@ public: static void show(const LLRect &rect, void (*callback)(S32 option, void* user_data), void* callback_data); + static void reshapePanel(); static void populateFields(LLPointer credential, bool remember_user, bool remember_psswrd); static void resetFields(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5dd3270b2e..c60a67f79d 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2407,6 +2407,11 @@ void LLViewerWindow::reshape(S32 width, S32 height) // round up when converting coordinates to make sure there are no gaps at edge of window LLView::sForceReshape = display_scale_changed; mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY])); + if (display_scale_changed) + { + // Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass() + LLPanelLogin::reshapePanel(); + } LLView::sForceReshape = FALSE; // clear font width caches -- cgit v1.2.3 From 61e318564e5c492ff7da70ef05f9596c4af8d369 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 17 Aug 2020 16:46:19 +0300 Subject: SL-13784 Highlight friends' names in Conversations floater --- indra/newview/llconversationview.cpp | 35 +++++++++++++++++++++++++++++++--- indra/newview/llconversationview.h | 3 +++ indra/newview/skins/default/colors.xml | 3 +++ 3 files changed, 38 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 60a5204547..0ca4679ea4 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -31,6 +31,7 @@ #include #include "llagentdata.h" +#include "llavataractions.h" #include "llconversationmodel.h" #include "llfloaterimsession.h" #include "llfloaterimnearbychat.h" @@ -432,8 +433,13 @@ void LLConversationViewSession::refresh() vmi->resetRefresh(); if (mSessionTitle) - { - mSessionTitle->setText(vmi->getDisplayName()); + { + if (!highlightFriendTitle(vmi)) + { + LLStyle::Params title_style; + title_style.color = LLUIColorTable::instance().getColor("LabelTextColor"); + mSessionTitle->setText(vmi->getDisplayName(), title_style); + } } // Update all speaking indicators @@ -478,6 +484,22 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi } } +bool LLConversationViewSession::highlightFriendTitle(LLConversationItem* vmi) +{ + if(vmi->getType() == LLConversationItem::CONV_PARTICIPANT || vmi->getType() == LLConversationItem::CONV_SESSION_1_ON_1) + { + LLIMModel::LLIMSession* session= LLIMModel::instance().findIMSession(vmi->getUUID()); + if (session && LLAvatarActions::isFriend(session->mOtherParticipantID)) + { + LLStyle::Params title_style; + title_style.color = LLUIColorTable::instance().getColor("ConversationFriendColor"); + mSessionTitle->setText(vmi->getDisplayName(), title_style); + return true; + } + } + return false; +} + // // Implementation of conversations list participant (avatar) widgets // @@ -576,7 +598,14 @@ void LLConversationViewParticipant::draw() } else { - color = mIsSelected ? sHighlightFgColor : sFgColor; + if (LLAvatarActions::isFriend(mUUID)) + { + color = LLUIColorTable::instance().getColor("ConversationFriendColor"); + } + else + { + color = mIsSelected ? sHighlightFgColor : sFgColor; + } } LLConversationItemParticipant* participant_model = dynamic_cast(getViewModelItem()); diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 420c250dfe..5b2fd6b7c4 100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -35,6 +35,7 @@ class LLTextBox; class LLFloaterIMContainer; +class LLConversationItem; class LLConversationViewSession; class LLConversationViewParticipant; @@ -92,6 +93,8 @@ public: LLFloater* getSessionFloater(); bool isInActiveVoiceChannel() { return mIsInActiveVoiceChannel; } + bool highlightFriendTitle(LLConversationItem* vmi); + private: void onCurrentVoiceSessionChanged(const LLUUID& session_id); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index e0da7f5d9e..601d5621a9 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -333,6 +333,9 @@ + -- cgit v1.2.3 From 5a77098523767aa8eb48c9c88068e1c38da0f958 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 18 Aug 2020 22:10:55 +0300 Subject: Buildfix # Conflicts: # indra/newview/llviewermenufile.cpp --- indra/newview/llimprocessing.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index ab98c5f50f..e1b58dde51 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1616,10 +1616,6 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) { from_group = message_data["from_group"].asString() == "Y"; } - else - { - from_group = message_data["from_group"].asString() == "Y"; - } LLIMProcessing::processNewMessage( -- cgit v1.2.3 From 18428e768d53f97694104d49da8ef4287568edda Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 19 Aug 2020 19:09:53 +0300 Subject: SL-12905 Use TLS-enabled map server --- indra/newview/app_settings/settings.xml | 2 +- indra/newview/llstartup.cpp | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index a00aa86d78..a18492c554 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5924,7 +5924,7 @@ Type String Value - http://map.secondlife.com.s3.amazonaws.com/ + https://map.secondlife.com/ CurrentMapServerURL diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6d20dcf188..9c3ad0bb28 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3519,11 +3519,6 @@ bool process_login_success_response() } // Request the map server url - // Non-agni grids have a different default location. - if (!LLGridManager::getInstance()->isInProductionGrid()) - { - gSavedSettings.setString("MapServerURL", "http://test.map.secondlife.com.s3.amazonaws.com/"); - } std::string map_server_url = response["map-server-url"]; if(!map_server_url.empty()) { -- cgit v1.2.3 From 02166bcf2a7bccb6fecacbbb88d48b265506be41 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 2 Sep 2020 15:23:17 +0300 Subject: SL-13890 Show appropriate message for empty 'Marketplace Listings' tabs --- indra/newview/llfloatermarketplacelistings.cpp | 3 +++ indra/newview/llinventoryfilter.cpp | 19 ++++++++++++++++--- indra/newview/llinventoryfilter.h | 2 ++ indra/newview/skins/default/xui/en/strings.xml | 1 + 4 files changed, 22 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 889d017389..524162ba51 100644 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -103,14 +103,17 @@ void LLPanelMarketplaceListings::buildAllPanels() panel = buildInventoryPanel("Active Items", "panel_marketplace_listings_listed.xml"); panel->getFilter().setFilterMarketplaceActiveFolders(); panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); + panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing"); panel->getFilter().markDefault(); panel = buildInventoryPanel("Inactive Items", "panel_marketplace_listings_unlisted.xml"); panel->getFilter().setFilterMarketplaceInactiveFolders(); panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); + panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing"); panel->getFilter().markDefault(); panel = buildInventoryPanel("Unassociated Items", "panel_marketplace_listings_unassociated.xml"); panel->getFilter().setFilterMarketplaceUnassociatedFolders(); panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); + panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing"); panel->getFilter().markDefault(); // Set the tab panel diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 745b953996..6e46713e04 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -74,6 +74,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p) : mName(p.name), mFilterModified(FILTER_NONE), mEmptyLookupMessage("InventoryNoMatchingItems"), + mDefaultEmptyLookupMessage(""), mFilterOps(p.filter_ops), mBackupFilterOps(mFilterOps), mFilterSubString(p.substring), @@ -1409,12 +1410,24 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message) mEmptyLookupMessage = message; } +void LLInventoryFilter::setDefaultEmptyLookupMessage(const std::string& message) +{ + mDefaultEmptyLookupMessage = message; +} + std::string LLInventoryFilter::getEmptyLookupMessage() const { - LLStringUtil::format_map_t args; - args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig()); + if (isDefault() && !mDefaultEmptyLookupMessage.empty()) + { + return LLTrans::getString(mDefaultEmptyLookupMessage); + } + else + { + LLStringUtil::format_map_t args; + args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig()); - return LLTrans::getString(mEmptyLookupMessage, args); + return LLTrans::getString(mEmptyLookupMessage, args); + } } diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index be02ee3623..61cc5ae602 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -257,6 +257,7 @@ public: EFilterCreatorType getFilterCreatorType() const; void setEmptyLookupMessage(const std::string& message); + void setDefaultEmptyLookupMessage(const std::string& message); std::string getEmptyLookupMessage() const; // +-------------------------------------------------------------------+ @@ -332,6 +333,7 @@ private: std::string mFilterText; std::string mEmptyLookupMessage; + std::string mDefaultEmptyLookupMessage; ESearchType mSearchType; diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 29eb733d41..3964c749be 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2297,6 +2297,7 @@ For AI Character: Get the closest navigable point to the point provided. Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters]. Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search]. Drag a landmark here to add it to your favorites. + You have no listings yet. No items found. Check the spelling of your search string and try again. You do not have a copy of this texture in your inventory Your Marketplace purchases will appear here. You may then drag them into your inventory to use them. -- cgit v1.2.3 From e9d50aeb3d1fa6b6251296f792d75cbc480f68fb Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 4 Sep 2020 20:12:48 +0300 Subject: SL-12243 Add a 'question mark' button into 'publishing classified' floater --- indra/newview/skins/default/xui/en/floater_publish_classified.xml | 1 + 1 file changed, 1 insertion(+) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/floater_publish_classified.xml b/indra/newview/skins/default/xui/en/floater_publish_classified.xml index 322e34272c..84e0b489d0 100644 --- a/indra/newview/skins/default/xui/en/floater_publish_classified.xml +++ b/indra/newview/skins/default/xui/en/floater_publish_classified.xml @@ -6,6 +6,7 @@ layout="topleft" name="publish_classified" title="Publishing Classified" + help_topic="profile_edit_classified" width="320"> Date: Fri, 6 Nov 2020 19:13:09 +0200 Subject: Reapplied SL-11215: Add release notes URLs to update-related notifications. In scope of SL-13740 work, this reverts commit 1935d25c78bf46f0fdc8758b6f215f53d17fd94a. --- indra/newview/lllogininstance.cpp | 26 ++++++++++++++++++---- .../newview/skins/default/xui/en/notifications.xml | 5 +++++ 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 0f846c152a..9d54c8c9c5 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -332,7 +332,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) { data["certificate"] = response["certificate"]; } - + if (gViewerWindow) gViewerWindow->setShowProgress(FALSE); @@ -349,13 +349,31 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) // login.cgi is insisting on a required update. We were called with an // event that bundles both the login.cgi 'response' and the // synchronization event from the 'updater'. - std::string required_version = response["message_args"]["VERSION"]; - LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL; + std::string login_version = response["message_args"]["VERSION"]; + std::string vvm_version = updater["VERSION"]; + std::string relnotes = updater["URL"]; + LL_WARNS("LLLogin") << "Login failed because an update to version " << login_version << " is required." << LL_ENDL; + // vvm_version might be empty because we might not have gotten + // SLVersionChecker's LoginSync handshake. But if it IS populated, it + // should (!) be the same as the version we got from login.cgi. + if ((! vvm_version.empty()) && vvm_version != login_version) + { + LL_WARNS("LLLogin") << "VVM update version " << vvm_version + << " differs from login version " << login_version + << "; presenting VVM version to match release notes URL" + << LL_ENDL; + login_version = vvm_version; + } + if (relnotes.empty()) + { + // I thought this would be available in strings.xml or some such + relnotes = "https://secondlife.com/support/downloads/"; + } if (gViewerWindow) gViewerWindow->setShowProgress(FALSE); - LLSD args(LLSDMap("VERSION", required_version)); + LLSD args(LLSDMap("VERSION", login_version)("URL", relnotes)); if (updater.isUndefined()) { // If the updater failed to shake hands, better advise the user to diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a0d56a0d08..b6fabd2bc4 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4039,6 +4039,8 @@ Finished download of raw terrain file to: [DOWNLOAD_PATH]. + Version [VERSION] is required for login. +Release notes: [URL] Click OK to download and install. confirm Version [VERSION] has been downloaded and is ready to install. +Release notes: [URL] Click OK to install. confirm Version [VERSION] has been downloaded and is ready to install. +Release notes: [URL] Proceed? confirm Date: Fri, 6 Nov 2020 19:51:36 +0200 Subject: SL-13283 Update favicons with new logo --- indra/newview/icons/release/secondlife.icns | Bin 228390 -> 113020 bytes indra/newview/icons/release/secondlife.ico | Bin 77552 -> 32988 bytes indra/newview/icons/release/secondlife_128.png | Bin 15184 -> 5320 bytes indra/newview/icons/release/secondlife_16.png | Bin 1009 -> 669 bytes indra/newview/icons/release/secondlife_256.BMP | Bin 196662 -> 131128 bytes indra/newview/icons/release/secondlife_256.png | Bin 47740 -> 11572 bytes indra/newview/icons/release/secondlife_32.png | Bin 2237 -> 1283 bytes indra/newview/icons/release/secondlife_48.png | Bin 3748 -> 1958 bytes indra/newview/icons/release/secondlife_512.png | Bin 154396 -> 26697 bytes indra/newview/installers/windows/install_icon.BMP | Bin 262198 -> 131128 bytes indra/newview/installers/windows/install_icon.ico | Bin 367958 -> 32988 bytes .../newview/installers/windows/uninstall_icon.BMP | Bin 262198 -> 131128 bytes .../newview/installers/windows/uninstall_icon.ico | Bin 367958 -> 32988 bytes 13 files changed, 0 insertions(+), 0 deletions(-) (limited to 'indra') diff --git a/indra/newview/icons/release/secondlife.icns b/indra/newview/icons/release/secondlife.icns index e15e34140d..a30b51b67a 100644 Binary files a/indra/newview/icons/release/secondlife.icns and b/indra/newview/icons/release/secondlife.icns differ diff --git a/indra/newview/icons/release/secondlife.ico b/indra/newview/icons/release/secondlife.ico index 28bf1e7664..93d4fa54ba 100644 Binary files a/indra/newview/icons/release/secondlife.ico and b/indra/newview/icons/release/secondlife.ico differ diff --git a/indra/newview/icons/release/secondlife_128.png b/indra/newview/icons/release/secondlife_128.png index 4c9544f498..2f21c1c7fc 100644 Binary files a/indra/newview/icons/release/secondlife_128.png and b/indra/newview/icons/release/secondlife_128.png differ diff --git a/indra/newview/icons/release/secondlife_16.png b/indra/newview/icons/release/secondlife_16.png index bb3168b8be..68f1427309 100644 Binary files a/indra/newview/icons/release/secondlife_16.png and b/indra/newview/icons/release/secondlife_16.png differ diff --git a/indra/newview/icons/release/secondlife_256.BMP b/indra/newview/icons/release/secondlife_256.BMP index 74deedd7d3..dba2636803 100644 Binary files a/indra/newview/icons/release/secondlife_256.BMP and b/indra/newview/icons/release/secondlife_256.BMP differ diff --git a/indra/newview/icons/release/secondlife_256.png b/indra/newview/icons/release/secondlife_256.png index bece338a90..8f324910e7 100644 Binary files a/indra/newview/icons/release/secondlife_256.png and b/indra/newview/icons/release/secondlife_256.png differ diff --git a/indra/newview/icons/release/secondlife_32.png b/indra/newview/icons/release/secondlife_32.png index 736359c147..2b7cdef03d 100644 Binary files a/indra/newview/icons/release/secondlife_32.png and b/indra/newview/icons/release/secondlife_32.png differ diff --git a/indra/newview/icons/release/secondlife_48.png b/indra/newview/icons/release/secondlife_48.png index 07d39ae585..c2ef372dd7 100644 Binary files a/indra/newview/icons/release/secondlife_48.png and b/indra/newview/icons/release/secondlife_48.png differ diff --git a/indra/newview/icons/release/secondlife_512.png b/indra/newview/icons/release/secondlife_512.png index 53d1643f45..d8a0c2924d 100644 Binary files a/indra/newview/icons/release/secondlife_512.png and b/indra/newview/icons/release/secondlife_512.png differ diff --git a/indra/newview/installers/windows/install_icon.BMP b/indra/newview/installers/windows/install_icon.BMP index 09df573870..dba2636803 100644 Binary files a/indra/newview/installers/windows/install_icon.BMP and b/indra/newview/installers/windows/install_icon.BMP differ diff --git a/indra/newview/installers/windows/install_icon.ico b/indra/newview/installers/windows/install_icon.ico index efe6c4f323..93d4fa54ba 100644 Binary files a/indra/newview/installers/windows/install_icon.ico and b/indra/newview/installers/windows/install_icon.ico differ diff --git a/indra/newview/installers/windows/uninstall_icon.BMP b/indra/newview/installers/windows/uninstall_icon.BMP index 562b56676a..dba2636803 100644 Binary files a/indra/newview/installers/windows/uninstall_icon.BMP and b/indra/newview/installers/windows/uninstall_icon.BMP differ diff --git a/indra/newview/installers/windows/uninstall_icon.ico b/indra/newview/installers/windows/uninstall_icon.ico index 05e1546860..93d4fa54ba 100644 Binary files a/indra/newview/installers/windows/uninstall_icon.ico and b/indra/newview/installers/windows/uninstall_icon.ico differ -- cgit v1.2.3 From 1416c4d5c20f90f40093bd6b5a2b41414eaee54d Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Fri, 13 Nov 2020 17:51:41 +0000 Subject: Merged in marchcat/SL-13161 (pull request #375) SL-13161 Leftover change * SL-13161 Leftover change Approved-by: Andrey Kleshchev --- indra/newview/llfloatereditenvironmentbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp index 2a38f18b73..e888144b6a 100644 --- a/indra/newview/llfloatereditenvironmentbase.cpp +++ b/indra/newview/llfloatereditenvironmentbase.cpp @@ -197,7 +197,7 @@ void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase if (!settings || status) { LLSD args; - args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown"; + args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString(); LLNotificationsUtil::add("FailedToFindSettings", args); closeFloater(); return; -- cgit v1.2.3 From 12d2bf47865559a8da087f6e3bbb4b65d421169c Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Wed, 18 Nov 2020 21:09:57 +0200 Subject: SL-14286 fixed crash when closing viewer while file picker is open --- indra/newview/llappdelegate-objc.mm | 1 + indra/newview/llfloatermodelpreview.cpp | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'indra') diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index a2b7362608..3f1b5139c5 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -134,6 +134,7 @@ // called again. Since it returned false, do not yet cancel // frameTimer. handleQuit(); + [[NSApplication sharedApplication] stopModal]; return NSTerminateCancel; } else { // pumpMainLoop() returned true: it's done. Okay, done with frameTimer. diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index b9c03f66a3..999e4a9582 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -103,6 +103,11 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod) void LLMeshFilePicker::notify(const std::vector& filenames) { + if(LLAppViewer::instance()->quitRequested()) + { + return; + } + if (filenames.size() > 0) { mMP->loadModel(filenames[0], mLOD); -- cgit v1.2.3 From a55ec705855d169e953cec10b42b156a3423fd94 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 19 Nov 2020 16:56:10 +0000 Subject: SL-14347 Crash at ChoosePixelFormat --- indra/llwindow/llwindowwin32.cpp | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'indra') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index a541e06c93..28e835a5fa 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -461,7 +461,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp)); memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp)); mCustomGammaSet = FALSE; - + mWindowHandle = NULL; + if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0)) { mMouseVanish = TRUE; @@ -1171,7 +1172,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO << " Height: " << (window_rect.bottom - window_rect.top) << " Fullscreen: " << mFullscreen << LL_ENDL; - if (!destroy_window_handler(mWindowHandle)) + if (mWindowHandle && !destroy_window_handler(mWindowHandle)) { LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL; } @@ -1230,13 +1231,26 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ; - if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) - { - close(); - OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), - mCallbacks->translateString("MBError"), OSMB_OK); - return FALSE; - } + try + { + // Looks like ChoosePixelFormat can crash in case of faulty driver + if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) + { + LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL; + OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), + mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } + } + catch (...) + { + LL_WARNS("Window") << "ChoosePixelFormat failed." << LL_ENDL; + OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), + mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ; @@ -1496,7 +1510,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO } // Destroy The Window - if (!destroy_window_handler(mWindowHandle)) + if (mWindowHandle && !destroy_window_handler(mWindowHandle)) { LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL; } -- cgit v1.2.3 From 47bd603ceb2862f0aa389f8beb5376f0d6fdfcf9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 25 Nov 2020 18:09:18 +0200 Subject: SL-13733 One more vivox shutdown crash Vivox was using dead pump --- indra/newview/llappviewer.cpp | 1 + indra/newview/llviewerwindow.cpp | 1 - indra/newview/llvoiceclient.cpp | 1 + indra/newview/llvoicevivox.cpp | 14 +++++++++++--- 4 files changed, 13 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8045da66d0..0596df4ddb 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1620,6 +1620,7 @@ bool LLAppViewer::doFrame() } delete gServicePump; + gServicePump = NULL; destroyMainloopTimeout(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 0c81c44a57..cb37f268f2 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2323,7 +2323,6 @@ void LLViewerWindow::shutdownGL() LLViewerWindow::~LLViewerWindow() { LL_INFOS() << "Destroying Window" << LL_ENDL; - gDebugWindowProc = TRUE; // event catching, disable once we figure out cause for exit crashes destroyWindow(); delete mDebugText; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 377f3174f3..6991ca6698 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -180,6 +180,7 @@ void LLVoiceClient::terminate() { if (mVoiceModule) mVoiceModule->terminate(); mVoiceModule = NULL; + m_servicePump = NULL; } const LLVoiceVersionInfo LLVoiceClient::getVersion() diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index a8d668420e..0c4450bea8 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -391,7 +391,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient() void LLVivoxVoiceClient::init(LLPumpIO *pump) { // constructor will set up LLVoiceClient::getInstance() - LLVivoxVoiceClient::getInstance()->mPump = pump; + mPump = pump; // LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro", // boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance())); @@ -419,6 +419,7 @@ void LLVivoxVoiceClient::terminate() } sShuttingDown = true; + mPump = NULL; } //--------------------------------------------------- @@ -953,10 +954,15 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); - while (!mPump) - { // Can't do this until we have the pump available. + while (!mPump && !sShuttingDown) + { // Can't use the pump until we have it available. llcoro::suspend(); } + + if (sShuttingDown) + { + return false; + } // MBW -- Note to self: pumps and pipes examples in // indra/test/io.cpp @@ -969,8 +975,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() readChain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(mSocket))); readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser())); + mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS); + //--------------------------------------------------------------------- llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); -- cgit v1.2.3 From 71bca1d8609901d98e4dca5f2e264d5d4b497e6d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 26 Nov 2020 22:26:18 +0200 Subject: SL-14399 Enqueue into 'LLViewerAssetStorage::assetRequestCoro' failed --- indra/llmessage/llassetstorage.h | 2 +- indra/llmessage/llcoproceduremanager.cpp | 8 ++--- indra/llmessage/llcoproceduremanager.h | 3 ++ indra/newview/app_settings/settings.xml | 2 +- indra/newview/llviewerassetstorage.cpp | 51 +++++++++++++++++++++++++++----- indra/newview/llviewerassetstorage.h | 44 ++++++++++++++++++++++----- 6 files changed, 89 insertions(+), 21 deletions(-) (limited to 'indra') diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index c799d8eefc..7e4572f50f 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -262,7 +262,7 @@ public: virtual void logAssetStorageInfo() = 0; - void checkForTimeouts(); + virtual void checkForTimeouts(); void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype, diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index a4fe3a2a8e..4d76dacdf7 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -47,7 +47,7 @@ static const std::map DefaultPoolSizes{ }; static const U32 DEFAULT_POOL_SIZE = 5; -static const U32 DEFAULT_QUEUE_SIZE = 4096; +const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 4096; //========================================================================= class LLCoprocedurePool: private boost::noncopyable @@ -194,7 +194,7 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd mPropertyDefineFn = updatefn; // workaround until we get mutex into initializePool - initializePool("VAssetStorage"); + initializePool("AssetStorage"); initializePool("Upload"); } @@ -281,7 +281,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mPoolSize(size), mActiveCoprocsCount(0), mPending(0), - mPendingCoprocs(boost::make_shared(DEFAULT_QUEUE_SIZE)), + mPendingCoprocs(boost::make_shared(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)), mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), mCoroMapping() { @@ -332,7 +332,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter)); } - LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << DEFAULT_QUEUE_SIZE << LL_ENDL; + LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL; } LLCoprocedurePool::~LLCoprocedurePool() diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 70204ba02b..d5557c129f 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -91,6 +91,9 @@ private: SettingQuery_t mPropertyQueryFn; SettingUpdate_t mPropertyDefineFn; + +public: + static const U32 DEFAULT_QUEUE_SIZE; }; #endif diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 48a89b40a5..bd1b25c863 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -15147,7 +15147,7 @@ Value 1 - PoolSizeVAssetStorage + PoolSizeAssetStorage Comment Coroutine Pool size for AssetStorage requests diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 54f80a2995..7842d24279 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -49,8 +49,8 @@ /// LLViewerAssetRequest ///---------------------------------------------------------------------------- - // There is also PoolSizeVAssetStorage value in setting that should mirror this name -static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "VAssetStorage"; + // There is also PoolSizeAssetStorage value in setting that should mirror this name +static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "AssetStorage"; /** * @brief Local class to encapsulate asset fetch requests with a timestamp. @@ -137,6 +137,14 @@ LLViewerAssetStorage::~LLViewerAssetStorage() // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later. LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL); } + + while (mCoroWaitList.size() > 0) + { + CoroWaitList &request = mCoroWaitList.front(); + // Clean up pending downloads, delete request and trigger callbacks + removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE); + mCoroWaitList.pop_front(); + } } // virtual @@ -350,6 +358,27 @@ void LLViewerAssetStorage::storeAssetData( } } +void LLViewerAssetStorage::checkForTimeouts() +{ + LLAssetStorage::checkForTimeouts(); + + // Restore requests + LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); + while (mCoroWaitList.size() > 0 + && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) + { + CoroWaitList &request = mCoroWaitList.front(); + + bool with_http = true; + bool is_temp = false; + LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp); + + manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", + boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData)); + + mCoroWaitList.pop_front(); + } +} /** * @brief Allocate and queue an asset fetch request for the viewer @@ -407,12 +436,20 @@ void LLViewerAssetStorage::queueRequestHttp( // This is the same as the current UDP logic - don't re-request a duplicate. if (!duplicate) { - bool with_http = true; - bool is_temp = false; - LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); + // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit + if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) + { + bool with_http = true; + bool is_temp = false; + LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); - LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL,"LLViewerAssetStorage::assetRequestCoro", - boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); + LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", + boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); + } + else + { + mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data); + } } } diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index ef01d179b7..5af16bd73e 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -45,7 +45,7 @@ public: ~LLViewerAssetStorage(); - virtual void storeAssetData( + void storeAssetData( const LLTransactionID& tid, LLAssetType::EType atype, LLStoreAssetCallback callback, @@ -54,9 +54,9 @@ public: bool is_priority = false, bool store_local = false, bool user_waiting=FALSE, - F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); - - virtual void storeAssetData( + F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; + + void storeAssetData( const std::string& filename, const LLTransactionID& tid, LLAssetType::EType type, @@ -65,16 +65,17 @@ public: bool temp_file = false, bool is_priority = false, bool user_waiting=FALSE, - F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); + F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; + + void checkForTimeouts() override; protected: - // virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback, void *user_data, BOOL duplicate, - BOOL is_priority); + BOOL is_priority) override; void queueRequestHttp(const LLUUID& uuid, LLAssetType::EType type, @@ -94,7 +95,34 @@ protected: std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); void logAssetStorageInfo(); - + + // Asset storage works through coroutines and coroutines have limited queue capacity + // This class is meant to temporary store requests when fiber's queue is full + class CoroWaitList + { + public: + CoroWaitList(LLViewerAssetRequest *req, + const LLUUID& uuid, + LLAssetType::EType atype, + LLGetAssetCallback &callback, + void *user_data) + : mRequest(req), + mId(uuid), + mType(atype), + mCallback(callback), + mUserData(user_data) + { + } + + LLViewerAssetRequest* mRequest; + LLUUID mId; + LLAssetType::EType mType; + LLGetAssetCallback mCallback; + void *mUserData; + }; + typedef std::list wait_list_t; + wait_list_t mCoroWaitList; + std::string mViewerAssetUrl; S32 mAssetCoroCount; S32 mCountRequests; -- cgit v1.2.3 From 54a5e4de5790e0cbe1198d8242dc6517ee9b58c7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 27 Nov 2020 20:56:25 +0200 Subject: SL-14399 Mac build fix --- indra/newview/llviewerassetstorage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 5af16bd73e..c1a5534b81 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -94,7 +94,7 @@ protected: std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); - void logAssetStorageInfo(); + void logAssetStorageInfo() override; // Asset storage works through coroutines and coroutines have limited queue capacity // This class is meant to temporary store requests when fiber's queue is full -- cgit v1.2.3 From 6d06c8b9de4708c4b8d8c68ae5fe4d753b9d70ca Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Dec 2020 17:08:35 +0200 Subject: SL-13733 One more vivox shutdown crash #2 --- indra/newview/llvoicevivox.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra') diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 0c4450bea8..f9ffefd4a2 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1001,6 +1001,11 @@ bool LLVivoxVoiceClient::provisionVoiceAccount() // *TODO* Pump a message for wake up. llcoro::suspend(); } + + if (sShuttingDown) + { + return false; + } std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest"); -- cgit v1.2.3 From bb4d02446fa215520a11f219ebca453d2dea0388 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Dec 2020 18:21:43 +0200 Subject: SL-14347 Crash at ChoosePixelFormat SEH --- indra/llcommon/llcoros.cpp | 22 +--------------------- indra/llcommon/llexception.cpp | 25 +++++++++++++++++++++++++ indra/llcommon/llexception.h | 10 ++++++++++ indra/llwindow/llwindowwin32.cpp | 23 ++++++++++++++++++++--- indra/newview/llfeaturemanager.cpp | 18 +----------------- 5 files changed, 57 insertions(+), 41 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 262929006d..23419a52a7 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -56,10 +56,6 @@ #include "stringize.h" #include "llexception.h" -#if LL_WINDOWS -#include -#endif - // static LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) { @@ -253,29 +249,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl #if LL_WINDOWS -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific - -U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) -{ - if (code == STATUS_MSC_EXCEPTION) - { - // C++ exception, go on - return EXCEPTION_CONTINUE_SEARCH; - } - else - { - // handle it - return EXCEPTION_EXECUTE_HANDLER; - } -} - void LLCoros::winlevel(const callable_t& callable) { __try { callable(); } - __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) + __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) { // convert to C++ styled exception // Note: it might be better to use _se_set_translator diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 5ce8958687..b584b0ff8b 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -24,11 +24,14 @@ // `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if // _Unwind_Backtrace is available without `_GNU_SOURCE`." #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED + #if LL_WINDOWS // On Windows, header-only implementation causes macro collisions -- use // prebuilt library #define BOOST_STACKTRACE_LINK +#include #endif // LL_WINDOWS + #include // other Linden headers #include "llerror.h" @@ -85,3 +88,25 @@ void annotate_exception_(boost::exception& exc) // Anyway, which of us is really going to examine more than 100 frames? exc << errinfo_stacktrace(boost::stacktrace::stacktrace(1, 100)); } + +#if LL_WINDOWS + +// For windows SEH exception handling we sometimes need a filter that will +// separate C++ exceptions from C SEH exceptions +static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + +U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) +{ + if (code == STATUS_MSC_EXCEPTION) + { + // C++ exception, go on + return EXCEPTION_CONTINUE_SEARCH; + } + else + { + // handle it + return EXCEPTION_EXECUTE_HANDLER; + } +} + +#endif //LL_WINDOWS diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h index 422dd8810a..375bea4a57 100644 --- a/indra/llcommon/llexception.h +++ b/indra/llcommon/llexception.h @@ -102,4 +102,14 @@ void crash_on_unhandled_exception_(const char*, int, const char*, const std::str log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) void log_unhandled_exception_(const char*, int, const char*, const std::string&); + +#if LL_WINDOWS + +// SEH exception filtering for use in __try __except +// Separates C++ exceptions from C SEH exceptions +// Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&); +U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop); + +#endif //LL_WINDOWS + #endif /* ! defined(LL_LLEXCEPTION_H) */ diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 28e835a5fa..36148190fa 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -38,6 +38,7 @@ // Linden library includes #include "llerror.h" +#include "llexception.h" #include "llfasttimer.h" #include "llgl.h" #include "llstring.h" @@ -117,7 +118,7 @@ void show_window_creation_error(const std::string& title) LL_WARNS("Window") << title << LL_ENDL; } -HGLRC SafeCreateContext(HDC hdc) +HGLRC SafeCreateContext(HDC &hdc) { __try { @@ -129,6 +130,22 @@ HGLRC SafeCreateContext(HDC hdc) } } +GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd) +{ + __try + { + return ChoosePixelFormat(hdc, ppfd); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + // convert to C++ styled exception + // C exception don't allow classes, so it's a regular char array + char integer_string[32]; + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); + throw std::exception(integer_string); + } +} + //static BOOL LLWindowWin32::sIsClassRegistered = FALSE; @@ -1234,7 +1251,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO try { // Looks like ChoosePixelFormat can crash in case of faulty driver - if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) + if (!(pixel_format = SafeChoosePixelFormat(mhDC, &pfd))) { LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL; OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), @@ -1245,7 +1262,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO } catch (...) { - LL_WARNS("Window") << "ChoosePixelFormat failed." << LL_ENDL; + LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat"); OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), mCallbacks->translateString("MBError"), OSMB_OK); close(); diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index d915a9fd26..dc9816c9f7 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -379,22 +379,6 @@ F32 gpu_benchmark(); #if LL_WINDOWS -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific - -U32 exception_benchmark_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) -{ - if (code == STATUS_MSC_EXCEPTION) - { - // C++ exception, go on - return EXCEPTION_CONTINUE_SEARCH; - } - else - { - // handle it - return EXCEPTION_EXECUTE_HANDLER; - } -} - F32 logExceptionBenchmark() { // Todo: make a wrapper/class for SEH exceptions @@ -403,7 +387,7 @@ F32 logExceptionBenchmark() { gbps = gpu_benchmark(); } - __except (exception_benchmark_filter(GetExceptionCode(), GetExceptionInformation())) + __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) { // convert to C++ styled exception char integer_string[32]; -- cgit v1.2.3 From 5691d302ef876a7e6fb6861441f14e5e7f0c7735 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Jul 2020 13:36:43 +0000 Subject: SL-12069 Issues with bakes-on-mesh and alpha modes --- indra/llprimitive/llmaterial.cpp | 40 +++++- indra/llprimitive/llmaterial.h | 11 ++ indra/newview/lldrawpoolavatar.cpp | 4 +- indra/newview/llface.cpp | 4 +- indra/newview/llviewerobject.cpp | 191 +++++++++++++++++++++++++--- indra/newview/llviewerobject.h | 24 +++- indra/newview/llvovolume.cpp | 254 ++----------------------------------- indra/newview/llvovolume.h | 20 --- indra/newview/pipeline.cpp | 2 +- 9 files changed, 259 insertions(+), 291 deletions(-) (limited to 'indra') diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index a219ac1450..a1bfc4edd9 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -28,6 +28,8 @@ #include "llmaterial.h" +#include "../llrender/llglheaders.h" + /** * Materials cap parameters */ @@ -105,6 +107,8 @@ LLMaterial::LLMaterial() , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT) , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY) , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + , mDiffuseFormatPrimary(GL_RGBA) + , mDiffuseBaked(false) , mAlphaMaskCutoff(0) { } @@ -311,6 +315,20 @@ void LLMaterial::setEnvironmentIntensity(U8 intensity) mEnvironmentIntensity = intensity; } +U8 LLMaterial::getDiffuseAlphaModeRender() const +{ + if (mDiffuseBaked + || mDiffuseFormatPrimary == GL_RGBA + || mDiffuseFormatPrimary == GL_ALPHA) + { + return mDiffuseAlphaMode; + } + else + { + return DIFFUSE_ALPHA_MODE_NONE; + } +} + U8 LLMaterial::getDiffuseAlphaMode() const { return mDiffuseAlphaMode; @@ -321,6 +339,26 @@ void LLMaterial::setDiffuseAlphaMode(U8 alpha_mode) mDiffuseAlphaMode = alpha_mode; } +U32 LLMaterial::getDiffuseFormatPrimary() const +{ + return mDiffuseFormatPrimary; +} + +void LLMaterial::setDiffuseFormatPrimary(U32 format_primary) +{ + mDiffuseFormatPrimary = format_primary; +} + +bool LLMaterial::getIsDiffuseBaked() const +{ + return mDiffuseBaked; +} + +void LLMaterial::setDiffuseBaked(bool baked) +{ + mDiffuseBaked = baked; +} + U8 LLMaterial::getAlphaMaskCutoff() const { return mAlphaMaskCutoff; @@ -437,7 +475,7 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode) } else { - ret = getDiffuseAlphaMode(); + ret = getDiffuseAlphaModeRender(); } llassert(ret < SHADER_COUNT); diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index d58b7ee812..1207917568 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -115,8 +115,17 @@ public: void setSpecularLightExponent(U8 exponent); U8 getEnvironmentIntensity() const; void setEnvironmentIntensity(U8 intensity); + + // getDiffuseAlphaModeRender takes into account if image supports alpha + // and returns value apropriate for render + // getDiffuseAlphaMode() returns value as is + U8 getDiffuseAlphaModeRender() const; U8 getDiffuseAlphaMode() const; void setDiffuseAlphaMode(U8 alpha_mode); + U32 getDiffuseFormatPrimary() const; + void setDiffuseFormatPrimary(U32 format_primary); + bool getIsDiffuseBaked() const; + void setDiffuseBaked(bool baked); U8 getAlphaMaskCutoff() const; void setAlphaMaskCutoff(U8 cutoff); @@ -147,6 +156,8 @@ protected: U8 mSpecularLightExponent; U8 mEnvironmentIntensity; U8 mDiffuseAlphaMode; + U32 mDiffuseFormatPrimary; // value from texture, LLGLenum, is not included in fromLLSD/asLLSD + bool mDiffuseBaked; // is not included in fromLLSD/asLLSD U8 mAlphaMaskCutoff; }; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 87772d9eb6..17b5fde947 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -2120,7 +2120,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) if (mat) { - switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode())) + switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaModeRender())) { case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: { @@ -2258,7 +2258,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec); sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env); - if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { F32 cutoff = mat->getAlphaMaskCutoff()/255.f; sVertexProgram->setMinimumAlpha(cutoff); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 4a802ad9aa..01d8b6775b 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1165,7 +1165,7 @@ bool LLFace::canRenderAsMask() } LLMaterial* mat = te->getMaterialParams(); - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) { return false; } @@ -1412,7 +1412,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } else { - if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (!mat || mat->getDiffuseAlphaModeRender() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { shiny_in_alpha = true; } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b88baf6aa7..395dd0495f 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4880,22 +4880,78 @@ void LLViewerObject::refreshBakeTexture() } } +void LLViewerObject::updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture) +{ + // Objects getting non-alpha texture and alpha mask can result in graphical bugs, like white or red alphas. + // To resolve the issue this function provides image format to material and based on format material's + // getDiffuseAlphaModeRender() function will decide what value to provide to render + // + // Unfortunately LLMaterial has no access to diffuse image, so we have to set this data in LLViewerObject + // regardles of object being used/seen or frequency of image-updates. + mat->setDiffuseBaked(baked_texture); + + if (!baked_texture) + { + if (imagep->isMissingAsset()) + { + mat->setDiffuseFormatPrimary(0); + } + else if (0 == imagep->getPrimaryFormat()) + { + // We don't have information about this texture, wait for it + mWaitingTextureInfo.insert(uuid_material_mmap_t::value_type(imagep->getID(), material_info(LLRender::DIFFUSE_MAP, te))); + // Temporary assume RGBA image + mat->setDiffuseFormatPrimary(GL_RGBA); + } + else + { + mat->setDiffuseFormatPrimary(imagep->getPrimaryFormat()); + } + } +} + +S32 LLViewerObject::setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep) +{ + LLUUID new_id = imagep->getID(); + S32 retval = LLPrimitive::setTETexture(te, new_id); + + LLTextureEntry* tep = getTE(te); + LLUUID old_image_id = tep->getID(); + + LLViewerTexture* baked_texture = getBakedTextureForMagicId(new_id); + mTEImages[te] = baked_texture ? baked_texture : imagep; + updateAvatarMeshVisibility(new_id, old_image_id); + + LLMaterial* mat = tep->getMaterialParams(); + if (mat) + { + // Don't update format from texture (and don't shedule one) if material has no alpha mode set, + // just assume RGBA format, format will get updated with setTEMaterialParams call if mode changes + if (mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE) + { + bool baked = baked_texture != NULL; + updateDiffuseMatParams(te, mat, imagep, baked); + } + else + { + mat->setDiffuseFormatPrimary(GL_RGBA); + } + } + + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + + return retval; +} + void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) { if (mTEImages[te] != imagep) { - LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null; - - LLPrimitive::setTETexture(te, imagep->getID()); - - LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID()); - mTEImages[te] = baked_texture ? baked_texture : imagep; - updateAvatarMeshVisibility(imagep->getID(), old_image_id); - setChanged(TEXTURE); - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - } + setDiffuseImageAndParams(te, imagep); } } @@ -4907,15 +4963,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image) if (uuid != getTE(te)->getID() || uuid == LLUUID::null) { - retval = LLPrimitive::setTETexture(te, uuid); - LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid); - mTEImages[te] = baked_texture ? baked_texture : image; - updateAvatarMeshVisibility(uuid,old_image_id); - setChanged(TEXTURE); - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - } + retval = setDiffuseImageAndParams(te, image); } return retval; } @@ -5210,6 +5258,29 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri return 0; } + if (pMaterialParams.notNull() + && pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE) + { + // Don't update if no alpha is set. If alpha changes, this function will run again, + // no point in sheduling additional texture callbacks (in updateDiffuseMatParams) + LLTextureEntry* tex_entry = getTE(te); + bool is_baked = tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID()); + + LLViewerTexture *img_diffuse = getTEImage(te); + llassert(NULL != img_diffuse); + + if (NULL != img_diffuse) + { + // Will modify alpha mask provided to renderer to fit image + updateDiffuseMatParams(te, pMaterialParams.get(), img_diffuse, is_baked); + } + else + { + LLMaterial *mat = pMaterialParams.get(); // to avoid const + mat->setDiffuseFormatPrimary(0); + } + } + retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams); LL_DEBUGS("Material") << "Changing material params for te " << (S32)te << ", object " << mID @@ -5222,6 +5293,84 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri return retval; } +bool LLViewerObject::notifyAboutCreatingTexture(LLViewerTexture *texture) +{ + // Confirmation about texture creation, check wait-list + // and make changes, or return false + + std::pair range = mWaitingTextureInfo.equal_range(texture->getID()); + + bool refresh_materials = false; + + // RGB textures without alpha channels won't work right with alpha, + // we provide format to material for material to decide when to drop alpha + for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it) + { + LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); + if (cur_material.notNull() + && LLRender::DIFFUSE_MAP == range_it->second.map) + { + U32 format = texture->getPrimaryFormat(); + if (format != cur_material->getDiffuseFormatPrimary()) + { + cur_material->setDiffuseFormatPrimary(format); + refresh_materials = true; + } + } + } //for + + if (refresh_materials) + { + LLViewerObject::refreshMaterials(); + } + + //clear wait-list + mWaitingTextureInfo.erase(range.first, range.second); + + return refresh_materials; +} + +bool LLViewerObject::notifyAboutMissingAsset(LLViewerTexture *texture) +{ + // When waiting information about texture it turned out to be missing. + // Confirm the state, update values accordingly + std::pair range = mWaitingTextureInfo.equal_range(texture->getID()); + if (range.first == range.second) return false; + + bool refresh_materials = false; + + for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it) + { + LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); + if (cur_material.isNull()) + continue; + + if (range_it->second.map == LLRender::DIFFUSE_MAP) + { + LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); + if (cur_material.notNull() + && LLRender::DIFFUSE_MAP == range_it->second.map) + { + if (0 != cur_material->getDiffuseFormatPrimary()) + { + cur_material->setDiffuseFormatPrimary(0); + refresh_materials = true; + } + } + } + } //for + + if (refresh_materials) + { + LLViewerObject::refreshMaterials(); + } + + //clear wait-list + mWaitingTextureInfo.erase(range.first, range.second); + + return refresh_materials; +} + void LLViewerObject::refreshMaterials() { setChanged(TEXTURE); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 250c4ac328..9444c4f788 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -768,7 +768,12 @@ protected: void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy); void deleteParticleSource(); void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); - + + // Helper function to modify alpha mask provided to render according to image (ex: RGB image will drop alpha mask) + void updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture); + // Shared part of code from setTEImage and setTETextureCore + S32 setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep); + private: void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string void deleteTEImages(); // correctly deletes list of images @@ -901,10 +906,27 @@ public: LLJointRiggingInfoTab mJointRiggingInfoTab; + bool notifyAboutCreatingTexture(LLViewerTexture *texture); + bool notifyAboutMissingAsset(LLViewerTexture *texture); + private: LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. EObjectUpdateType mLastUpdateType; BOOL mLastUpdateCached; + + struct material_info + { + LLRender::eTexIndex map; + U8 te; + + material_info(LLRender::eTexIndex map_, U8 te_) + : map(map_) + , te(te_) + {} + }; + + typedef std::multimap uuid_material_mmap_t; + uuid_material_mmap_t mWaitingTextureInfo; }; /////////////////// diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 492d37edba..93a84df270 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2290,243 +2290,11 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) return res; } -bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture) -{ //Ok, here we have confirmation about texture creation, check our wait-list - //and make changes, or return false - - std::pair range = mWaitingTextureInfo.equal_range(texture->getID()); - - typedef std::map map_te_material; - map_te_material new_material; - - for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) - { - LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); - - //here we just interesting in DIFFUSE_MAP only! - if(NULL != cur_material.get() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat()) - { //ok let's check the diffuse mode - switch(cur_material->getDiffuseAlphaMode()) - { - case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: - case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: - case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: - { //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE - - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - - } break; - } //switch - } //if - } //for - - //setup new materials - for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) - { - LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second); - LLViewerObject::setTEMaterialParams(it->first, it->second); - } - - //clear wait-list - mWaitingTextureInfo.erase(range.first, range.second); - - return 0 != new_material.size(); -} - -bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture) -{ //Ok, here if we wait information about texture and it's missing - //then depending from the texture map (diffuse, normal, or specular) - //make changes in material and confirm it. If not return false. - std::pair range = mWaitingTextureInfo.equal_range(texture->getID()); - if(range.first == range.second) return false; - - typedef std::map map_te_material; - map_te_material new_material; - - for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) - { - LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); - if (cur_material.isNull()) - continue; - - switch(range_it->second.map) - { - case LLRender::DIFFUSE_MAP: - { - if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode()) - { //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - } break; - case LLRender::NORMAL_MAP: - { //missing texture => reset material texture id - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setNormalID(LLUUID::null); - } break; - case LLRender::SPECULAR_MAP: - { //missing texture => reset material texture id - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setSpecularID(LLUUID::null); - } break; - case LLRender::NUM_TEXTURE_CHANNELS: - //nothing to do, make compiler happy - break; - } //switch - } //for - - //setup new materials - for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) - { - LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second); - LLViewerObject::setTEMaterialParams(it->first, it->second); - } - - //clear wait-list - mWaitingTextureInfo.erase(range.first, range.second); - - return 0 != new_material.size(); -} - S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) { - LLMaterialPtr pMaterial = const_cast(pMaterialParams); - - if(pMaterialParams) - { //check all of them according to material settings - - LLViewerTexture *img_diffuse = getTEImage(te); - LLViewerTexture *img_normal = getTENormalMap(te); - LLViewerTexture *img_specular = getTESpecularMap(te); - - llassert(NULL != img_diffuse); - - LLMaterialPtr new_material = NULL; - - //diffuse - if(NULL != img_diffuse) - { //guard - if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te))); - } - else - { - bool bSetDiffuseNone = false; - if(img_diffuse->isMissingAsset()) - { - bSetDiffuseNone = true; - } - else - { - switch(pMaterialParams->getDiffuseAlphaMode()) - { - case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: - case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: - case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: - { //all of them modes available only for 32 bit textures - LLTextureEntry* tex_entry = getTE(te); - bool bIsBakedImageId = false; - if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) - { - bIsBakedImageId = true; - } - if (GL_RGBA != img_diffuse->getPrimaryFormat() && !bIsBakedImageId) - { - bSetDiffuseNone = true; - } - } break; - } - } //else - - - if(bSetDiffuseNone) - { //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE - new_material = new LLMaterial(pMaterialParams->asLLSD()); - new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - } - } - - //normal - if(LLUUID::null != pMaterialParams->getNormalID()) - { - if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID()) - { - if(!new_material) { - new_material = new LLMaterial(pMaterialParams->asLLSD()); - } - new_material->setNormalID(LLUUID::null); - } - else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te))); - } - - } - - - //specular - if(LLUUID::null != pMaterialParams->getSpecularID()) - { - if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID()) - { - if(!new_material) { - new_material = new LLMaterial(pMaterialParams->asLLSD()); - } - new_material->setSpecularID(LLUUID::null); - } - else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te))); - } - } - - if(new_material) { - pMaterial = new_material; - LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial); - } - } - - S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial); + S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); - LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res + LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" ) << LL_ENDL; setChanged(ALL_CHANGED); @@ -4593,7 +4361,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& LLMaterial* mat = te->getMaterialParams(); if (mat) { - U8 mode = mat->getDiffuseAlphaMode(); + U8 mode = mat->getDiffuseAlphaModeRender(); if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE @@ -5239,7 +5007,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); - draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); + draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaModeRender(); draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); } else @@ -5601,7 +5369,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (mat && LLPipeline::sRenderDeferred) { - U8 alpha_mode = mat->getDiffuseAlphaMode(); + U8 alpha_mode = mat->getDiffuseAlphaModeRender(); bool is_alpha = type == LLDrawPool::POOL_ALPHA && (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND || @@ -5630,7 +5398,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else if (mat) { bool is_alpha = type == LLDrawPool::POOL_ALPHA; - U8 mode = mat->getDiffuseAlphaMode(); + U8 mode = mat->getDiffuseAlphaModeRender(); bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; @@ -6528,7 +6296,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace bool can_be_shiny = true; if (mat) { - U8 mode = mat->getDiffuseAlphaMode(); + U8 mode = mat->getDiffuseAlphaModeRender(); can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; } @@ -6550,7 +6318,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace // if (te->getFullbright()) { - if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { if (opaque) { @@ -6635,7 +6403,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } else if (mat) { - U8 mode = mat->getDiffuseAlphaMode(); + U8 mode = mat->getDiffuseAlphaModeRender(); is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)); @@ -6734,7 +6502,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } else if (fullbright || bake_sunlight) { //fullbright - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); } @@ -6756,7 +6524,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace else { //all around simple llassert(mask & LLVertexBuffer::MAP_NORMAL); - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { //material alpha mask can be respected in non-deferred registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index ce400a3498..97888ed869 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -441,26 +441,6 @@ protected: static S32 sNumLODChanges; friend class LLVolumeImplFlexible; - -public: - bool notifyAboutCreatingTexture(LLViewerTexture *texture); - bool notifyAboutMissingAsset(LLViewerTexture *texture); - -private: - struct material_info - { - LLRender::eTexIndex map; - U8 te; - - material_info(LLRender::eTexIndex map_, U8 te_) - : map(map_) - , te(te_) - {} - }; - - typedef std::multimap mmap_UUID_MAP_t; - mmap_UUID_MAP_t mWaitingTextureInfo; - }; #endif // LL_LLVOVOLUME_H diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 644934d1d8..71b71310b7 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1677,7 +1677,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima if (alpha && mat) { - switch (mat->getDiffuseAlphaMode()) + switch (mat->getDiffuseAlphaModeRender()) { case 1: alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. -- cgit v1.2.3 From db161b6f85a266ee9d883e3180874de898ccda0e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 5 Jan 2021 18:20:30 +0200 Subject: SL-14074 Resolved potential cause of conversation crashes Models (listeners) belong to folder-views, deleting all of them means that not only proper cleanup procedure won't be followed, and view might try clean dead pointer. --- indra/llui/llfolderviewmodel.h | 6 +++--- indra/newview/llconversationmodel.cpp | 3 +++ indra/newview/llparticipantlist.cpp | 7 ++----- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'indra') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 84a1539094..4739d4e6fe 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -204,6 +204,7 @@ public: virtual bool hasChildren() const = 0; virtual void addChild(LLFolderViewModelItem* child) = 0; virtual void removeChild(LLFolderViewModelItem* child) = 0; + virtual void clearChildren() = 0; // This method will be called to determine if a drop can be // performed, and will set drop to TRUE if a drop is @@ -301,9 +302,8 @@ public: virtual void clearChildren() { - // As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects - // This is different and not equivalent to calling removeChild() on each child - std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); + // We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest + std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); }); mChildren.clear(); dirtyDescendantsFilter(); dirtyFilter(); diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 4aa74a550c..8293dc6922 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -341,6 +341,9 @@ void LLConversationItemSession::removeParticipant(const LLUUID& participant_id) void LLConversationItemSession::clearParticipants() { + // clearParticipants function potentially is malfunctioning since it only cleans children of models, + // it does nothing to views that own those models (listeners) + // probably needs to post some kind of 'remove all participants' event clearChildren(); mIsLoaded = false; mNeedsRefresh = true; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index ee6893907e..94d20828ec 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -259,11 +259,7 @@ LLParticipantList::~LLParticipantList() */ void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id) { - LLConversationItemParticipant* participant = findParticipant(participant_id); - if (participant) - { - removeParticipant(participant); - } + removeParticipant(participant_id); // re-add avaline caller with a correct class instance. addAvatarIDExceptAgent(participant_id); } @@ -397,6 +393,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) // Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id)) // Add the participant model to the session's children list + // This will post "add_participant" event addParticipant(participant); adjustParticipant(avatar_id); -- cgit v1.2.3 From f86014ef151c7af64de4a08dc4c320e1743fb34b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 6 Jan 2021 00:45:07 +0200 Subject: SL-14270 Crash on participant's updateName Session was deleted before viewer had a chance to create view for listener, so listener ended up not deleted and avaiting an uptade, then tryed to call for deleted session. --- indra/newview/llconversationmodel.cpp | 14 +++++++++ indra/newview/llconversationmodel.h | 1 + indra/newview/llconversationview.cpp | 51 +++++++++++++++++++++++++++++++++ indra/newview/llconversationview.h | 2 ++ indra/newview/llfloaterimcontainer.cpp | 2 ++ indra/newview/llfloaterimsessiontab.cpp | 3 +- 6 files changed, 71 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 8293dc6922..fbdf08d8aa 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -349,6 +349,20 @@ void LLConversationItemSession::clearParticipants() mNeedsRefresh = true; } + +void LLConversationItemSession::deleteParticipantModels() +{ + // Make sure that no views exist before use and that view-owned items were removed! + // + // Normally we are not supposed to delete models directly, they should be + // owned by views and this action will result in crashes, but LLParticipantList + // creates models separately from views (it probably shouldn't) and then those + // models wait for idle cycles to be assigned to view. + // this code is meant to delete 'waiting' models + std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); + mChildren.clear(); +} + LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id) { // This is *not* a general tree parsing algorithm. It assumes that a session contains only diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 30c7481864..e30bfbb759 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -165,6 +165,7 @@ public: void removeParticipant(LLConversationItemParticipant* participant); void removeParticipant(const LLUUID& participant_id); void clearParticipants(); + void deleteParticipantModels(); // do not use while there are existing participant views LLConversationItemParticipant* findParticipant(const LLUUID& participant_id); void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted); diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 25971a7d52..71346b4b43 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -103,6 +103,57 @@ LLConversationViewSession::~LLConversationViewSession() mFlashTimer->unset(); } +void LLConversationViewSession::destroyView() +{ + // Chat can create and parent models(listeners) to session's model before creating + // coresponding views, such participant's models normally will wait for idle cycles + // but since we are deleting session and won't be processing any more events, make + // sure unowned models are removed as well. + // Might be good idea to just have an LLPointer list somewhere in LLConversationItemSession + + LLConversationItemSession* vmi = dynamic_cast(getViewModelItem()); + + // CONV_SESSION_1_ON_1 stores participants as two models that belong to views independent + // from session (nasty! These views are widgets in LLFloaterIMSessionTab, see buildConversationViewParticipant) + if (vmi && vmi->getType() != LLConversationItem::CONV_SESSION_1_ON_1) + { + // Destroy existing views + while (!mItems.empty()) + { + LLFolderViewItem *itemp = mItems.back(); + mItems.pop_back(); + + LLFolderViewModelItem* item_vmi = itemp->getViewModelItem(); + if (item_vmi) // supposed to exist + { + // unparent to remove from child list + vmi->removeChild(item_vmi); + } + itemp->destroyView(); + } + + // Not needed in scope of sessions, but just in case + while (!mFolders.empty()) + { + LLFolderViewFolder *folderp = mFolders.back(); + mFolders.pop_back(); + + LLFolderViewModelItem* folder_vmi = folderp->getViewModelItem(); + if (folder_vmi) + { + vmi->removeChild(folder_vmi); + } + folderp->destroyView(); + } + + // Now everything that is left in model(listener) is unowned, + // it is safe to remove + vmi->deleteParticipantModels(); + } + + LLFolderViewFolder::destroyView(); +} + void LLConversationViewSession::setFlashState(bool flash_state) { if (flash_state && !mFlashStateOn) diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 9762d56d57..0932d24dfe 100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -67,6 +67,8 @@ protected: public: virtual ~LLConversationViewSession(); + /*virtual*/ void destroyView(); + /*virtual*/ BOOL postBuild(); /*virtual*/ void draw(); /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 61b0fda18f..86c79791b8 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1822,6 +1822,8 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c { new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE); } + + // Will destroy views and delete models that are not assigned to any views widget->destroyView(); } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index fd3f8b21ce..e7f428c06a 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -534,8 +534,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); if (widget) { - mConversationsRoot->extractItem(widget); - delete widget; + widget->destroyView(); } mConversationsWidgets.erase(participant_id); } -- cgit v1.2.3 From 3d525fbf18568659722e6c4e4d93d96e2624498f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 15 Jan 2021 23:58:06 +0200 Subject: SL-14597 Pulled in updated uriparser Due to crash inside uriparser's code --- indra/cmake/Copy3rdPartyLibs.cmake | 2 ++ indra/newview/CMakeLists.txt | 2 ++ indra/newview/viewer_manifest.py | 4 ++++ 3 files changed, 8 insertions(+) (limited to 'indra') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 8efad33f71..578120f703 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -61,6 +61,7 @@ if(WINDOWS) nghttp2.dll glod.dll libhunspell.dll + uriparser.dll ) # Filenames are different for 32/64 bit BugSplat file and we don't @@ -165,6 +166,7 @@ elseif(DARWIN) libnghttp2.dylib libnghttp2.14.dylib libnghttp2.14.19.0.dylib + liburiparser.dylib ) if (FMODSTUDIO) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 95d54de7d8..85ba991ef0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1814,6 +1814,8 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll + ${SHARED_LIB_STAGING_DIR}/Release/uriparser.dll + ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/uriparser.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libsndfile-1.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 90a2af98f7..bc121c92ac 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -531,6 +531,9 @@ class WindowsManifest(ViewerManifest): # For textures self.path("openjpeg.dll") + # Uriparser + self.path("uriparser.dll") + # These need to be installed as a SxS assembly, currently a 'private' assembly. # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx self.path("msvcp140.dll") @@ -1033,6 +1036,7 @@ class DarwinManifest(ViewerManifest): # libnghttp2.major.dylib, which is a symlink to # libnghttp2.version.dylib. Get all of them. "libnghttp2.*dylib", + "liburiparser.dylib", ): dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) -- cgit v1.2.3 From a542ceb7e1667b7ee71c9f6bda4ea6e3f8583f53 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 16 Jan 2021 03:57:12 +0200 Subject: SL-14597 Updated Mac library name --- indra/cmake/URIPARSER.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/cmake/URIPARSER.cmake b/indra/cmake/URIPARSER.cmake index de146885a0..ecc5b74ef1 100644 --- a/indra/cmake/URIPARSER.cmake +++ b/indra/cmake/URIPARSER.cmake @@ -29,7 +29,7 @@ else (USESYSTEMLIBS) set(URIPARSER_PRELOAD_ARCHIVES -Wl,--whole-archive uriparser -Wl,--no-whole-archive) set(URIPARSER_LIBRARIES uriparser) elseif (DARWIN) - set(URIPARSER_LIBRARIES uriparser) + set(URIPARSER_LIBRARIES liburiparser.dylib) endif (WINDOWS) set(URIPARSER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/uriparser) endif (USESYSTEMLIBS) -- cgit v1.2.3 From 2f00eef6b40568643150af3bdb78c8b6ccf080c2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 16 Jan 2021 13:16:12 +0200 Subject: SL-14597 Fixed mac library only including symlink --- indra/cmake/Copy3rdPartyLibs.cmake | 2 ++ indra/newview/viewer_manifest.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 578120f703..de81512eef 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -167,6 +167,8 @@ elseif(DARWIN) libnghttp2.14.dylib libnghttp2.14.19.0.dylib liburiparser.dylib + liburiparser.1.dylib + liburiparser.1.0.27.dylib ) if (FMODSTUDIO) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index bc121c92ac..0c9fd3984b 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1036,7 +1036,7 @@ class DarwinManifest(ViewerManifest): # libnghttp2.major.dylib, which is a symlink to # libnghttp2.version.dylib. Get all of them. "libnghttp2.*dylib", - "liburiparser.dylib", + "liburiparser.*dylib", ): dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) -- cgit v1.2.3 From bee13995e42417c3e2b19b8f329eaec7528b1344 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 18 Jan 2021 10:46:46 +0200 Subject: SL-14597 Missed libraries for http test --- indra/llcorehttp/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'indra') diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 11b2e3e929..240ea2da83 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -178,6 +178,7 @@ if (DARWIN) libaprutil-1.0.dylib libexception_handler.dylib libnghttp2*.dylib + liburiparser*.dylib ${EXPAT_COPY} ) -- cgit v1.2.3 From bbd071f3d53b3a8169647f8594ce97ccdbc86f36 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 18 Jan 2021 17:10:21 +0200 Subject: SL-14597 ensure that uris don't crash viewer --- indra/llcommon/lluriparser.cpp | 51 +++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp index c275b90120..015ff2d7c3 100644 --- a/indra/llcommon/lluriparser.cpp +++ b/indra/llcommon/lluriparser.cpp @@ -163,26 +163,37 @@ S32 LLUriParser::normalize() mNormalizedTmp = mTmpScheme; if (!mRes) { - mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); - - if (!mRes) - { - S32 chars_required; - mRes = uriToStringCharsRequiredA(&mUri, &chars_required); - - if (!mRes) - { - chars_required++; - std::vector label_buf(chars_required); - mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL); - - if (!mRes) - { - mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; - mTmpScheme = false; - } - } - } + // Uriparser is 3p software we can not directly fix. + // On winodws this probably requires SEH handling, but all + // crashes so far were on MAC in scope of uriNormalizeSyntaxExA. + try + { + mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); + + if (!mRes) + { + S32 chars_required; + mRes = uriToStringCharsRequiredA(&mUri, &chars_required); + + if (!mRes) + { + chars_required++; + std::vector label_buf(chars_required); + mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL); + + if (!mRes) + { + mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; + mTmpScheme = false; + } + } + } + } + catch (...) + { + // At this point mNormalizedUri should contain http+unmodified input string. + LL_WARNS() << "Uriparser crashed processing: " << mNormalizedUri << LL_ENDL; + } } if(mTmpScheme) -- cgit v1.2.3 From 4eaf400c3619035172d15a8a29d0249e82427f84 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 21 Jan 2021 01:07:21 +0000 Subject: Merged in xcode-buildfix (pull request #442) xcode 12.3 buildfix * xcode 12.3 buildfix Approved-by: Andrey Kleshchev --- indra/llcommon/llsingleton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 83a4b64e8f..ad933154c2 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -388,7 +388,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort() // extracts just the first (key) element from each sorted_iterator, then // uses vec_t's range constructor... but frankly this is more // straightforward, as long as we remember the above reserve() call! - for (const SingletonDeps::sorted_iterator::value_type& pair : sdeps.sort()) + for (const SingletonDeps::sorted_iterator::value_type pair : sdeps.sort()) { ret.push_back(pair.first); } -- cgit v1.2.3 From bce4721097d33b324db0331ed40bb2e5f45c4d14 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 21 Jan 2021 11:59:27 +0000 Subject: SL-14597 Fixed deprecated function and added signal handling Signal handling is ugly, but so far that's the only option that works Approved-by: Maxim Nikolenko Approved-by: Andrey Lihatskiy --- indra/llcommon/lluriparser.cpp | 78 +++++++++++++++++++++++++++++------------- indra/llcommon/lluriparser.h | 1 - 2 files changed, 54 insertions(+), 25 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp index 015ff2d7c3..e4f229dd16 100644 --- a/indra/llcommon/lluriparser.cpp +++ b/indra/llcommon/lluriparser.cpp @@ -29,10 +29,13 @@ #include "linden_common.h" #include "lluriparser.h" +#if LL_DARWIN +#include +#include +#endif + LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0) { - mState.uri = &mUri; - if (u.find("://") == std::string::npos) { mNormalizedUri = "http://"; @@ -51,7 +54,7 @@ LLUriParser::~LLUriParser() S32 LLUriParser::parse() { - mRes = uriParseUriA(&mState, mNormalizedUri.c_str()); + mRes = uriParseSingleUriA(&mUri, mNormalizedUri.c_str(), NULL); return mRes; } @@ -158,42 +161,69 @@ void LLUriParser::extractParts() } } +#if LL_DARWIN +typedef void(*sighandler_t)(int); +jmp_buf return_to_normalize; +void uri_signal_handler(int signal) +{ + // Apparently signal handler throwing an exception doesn't work. + // This is ugly and unsafe due to not unwinding content of uriparser library, + // but unless we have a way to catch this as NSexception, jump appears to be the only option. + longjmp(return_to_normalize, 1 /*setjmp will return this value*/); +} +#endif + S32 LLUriParser::normalize() { mNormalizedTmp = mTmpScheme; if (!mRes) { - // Uriparser is 3p software we can not directly fix. - // On winodws this probably requires SEH handling, but all - // crashes so far were on MAC in scope of uriNormalizeSyntaxExA. - try +#if LL_DARWIN + sighandler_t last_handler; + last_handler = signal(SIGILL, &uri_signal_handler); // illegal instruction + if (setjmp(return_to_normalize)) + { + // Issue: external library crashed via signal + // If you encountered this, please try to figure out what's wrong: + // 1. Verify that library's input is 'sane' + // 2. Check if we have an NSexception to work with (unlikely) + // 3. See if passing same string causes exception to repeat + // + // Crash happens at uriNormalizeSyntaxExA + // Warning!!! This does not properly unwind stack, + // if this can be handled by NSexception, it needs to be remade + llassert(0); + + LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL; + signal(SIGILL, last_handler); + return 1; + } +#endif + + mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); + +#if LL_DARWIN + signal(SIGILL, last_handler); +#endif + + if (!mRes) { - mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); + S32 chars_required; + mRes = uriToStringCharsRequiredA(&mUri, &chars_required); if (!mRes) { - S32 chars_required; - mRes = uriToStringCharsRequiredA(&mUri, &chars_required); + chars_required++; + std::vector label_buf(chars_required); + mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL); if (!mRes) { - chars_required++; - std::vector label_buf(chars_required); - mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL); - - if (!mRes) - { - mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; - mTmpScheme = false; - } + mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; + mTmpScheme = false; } } } - catch (...) - { - // At this point mNormalizedUri should contain http+unmodified input string. - LL_WARNS() << "Uriparser crashed processing: " << mNormalizedUri << LL_ENDL; - } } if(mTmpScheme) diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h index cfbf54f3c8..92626b9054 100644 --- a/indra/llcommon/lluriparser.h +++ b/indra/llcommon/lluriparser.h @@ -76,7 +76,6 @@ private: std::string mFragment; std::string mNormalizedUri; - UriParserStateA mState; UriUriA mUri; S32 mRes; -- cgit v1.2.3 From a059e0d2e5f515376abc0a8a0d2c6ad32e3b2639 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 22 Jan 2021 22:59:26 +0200 Subject: SL-3136 Logout crash fixes from Ansariel Hiller --- indra/newview/llattachmentsmgr.cpp | 1 + indra/newview/llvoiceclient.cpp | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'indra') diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index d3e66289d1..0fd6009074 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -248,6 +248,7 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments() { if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(*it) && + !gAgentAvatarp->getWornAttachment(*it)->isTempAttachment() && // Don't link temp attachments in COF! !LLAppearanceMgr::instance().isLinkedInCOF(*it)) { LLUUID item_id = *it; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 6991ca6698..06e20038c5 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -181,6 +181,12 @@ void LLVoiceClient::terminate() if (mVoiceModule) mVoiceModule->terminate(); mVoiceModule = NULL; m_servicePump = NULL; + + // Shutdown speaker volume storage before LLSingletonBase::deleteAll() does it + if (LLSpeakerVolumeStorage::instanceExists()) + { + LLSpeakerVolumeStorage::deleteSingleton(); + } } const LLVoiceVersionInfo LLVoiceClient::getVersion() -- cgit v1.2.3 From a3d31ca683eb0744563b36d6432168fde6ae77d9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 26 Jan 2021 20:28:31 +0200 Subject: SL-14766 long unicode display names corrupt the conversation.log Contribution by Beq Janus --- indra/newview/llconversationlog.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'indra') diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index 9d78c528b6..fd59dd2601 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -535,7 +535,9 @@ bool LLConversationLog::loadFromFile(const std::string& filename) } bool purge_required = false; - char buffer[MAX_STRING]; + static constexpr int UTF_BUFFER{ 1024 }; // long enough to handle the most extreme Unicode nonsense and some to spare + + char buffer[UTF_BUFFER]; char conv_name_buffer[MAX_STRING]; char part_id_buffer[MAX_STRING]; char conv_id_buffer[MAX_STRING]; @@ -546,11 +548,14 @@ bool LLConversationLog::loadFromFile(const std::string& filename) // before CHUI-348 it was a flag of conversation voice state int prereserved_unused; - while (!feof(fp) && fgets(buffer, MAX_STRING, fp)) + memset(buffer, '\0', UTF_BUFFER); + while (!feof(fp) && fgets(buffer, UTF_BUFFER, fp)) { - conv_name_buffer[0] = '\0'; - part_id_buffer[0] = '\0'; - conv_id_buffer[0] = '\0'; + // force blank for added safety + memset(conv_name_buffer, '\0', MAX_STRING); + memset(part_id_buffer, '\0', MAX_STRING); + memset(conv_id_buffer, '\0', MAX_STRING); + memset(history_file_name, '\0', MAX_STRING); sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|", &time, @@ -587,6 +592,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename) } mConversations.push_back(conversation); + memset(buffer, '\0', UTF_BUFFER); } fclose(fp); -- cgit v1.2.3 From 9fc3014435aac812754f0d47b53c87526513113e Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 27 Jan 2021 18:32:41 +0200 Subject: SL-14422 Crash at LLSceneMonitor::dumpToFile --- indra/newview/llappviewer.cpp | 6 +- indra/newview/llscenemonitor.cpp | 218 ++++++++++++++++++++------------------- 2 files changed, 117 insertions(+), 107 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0596df4ddb..0a6906febc 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1678,7 +1678,11 @@ bool LLAppViewer::cleanup() //dump scene loading monitor results if (LLSceneMonitor::instanceExists()) { - LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); + if (!isSecondInstance()) + { + LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); + } + LLSceneMonitor::deleteSingleton(); } // There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 2c0c38dc75..a16cb81255 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -531,157 +531,163 @@ void LLSceneMonitor::dumpToFile(std::string file_name) if (!hasResults()) return; LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL; - - llofstream os(file_name.c_str()); - - os << std::setprecision(10); - - PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults(); - const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); - - F64Seconds frame_time; - - os << "Stat"; - for (S32 frame = 1; frame <= frame_count; frame++) + try { - frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); - os << ", " << frame_time.value(); - } - os << '\n'; + llofstream os(file_name.c_str()); - os << "Sample period(s)"; - for (S32 frame = 1; frame <= frame_count; frame++) - { - frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); - os << ", " << frame_time.value(); - } - os << '\n'; + os << std::setprecision(10); + PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults(); + const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); - typedef StatType trace_count; - for (auto& it : trace_count::instance_snapshot()) - { - std::ostringstream row; - row << std::setprecision(10); + F64Seconds frame_time; - row << it.getName(); - - const char* unit_label = it.getUnitLabel(); - if(unit_label[0]) + os << "Stat"; + for (S32 frame = 1; frame <= frame_count; frame++) { - row << "(" << unit_label << ")"; + frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); + os << ", " << frame_time.value(); } + os << '\n'; - S32 samples = 0; - + os << "Sample period(s)"; for (S32 frame = 1; frame <= frame_count; frame++) { - Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); - samples += recording.getSampleCount(it); - row << ", " << recording.getSum(it); + frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); + os << ", " << frame_time.value(); } + os << '\n'; - row << '\n'; - if (samples > 0) + typedef StatType trace_count; + for (auto& it : trace_count::instance_snapshot()) { - os << row.str(); - } - } - - typedef StatType trace_event; + std::ostringstream row; + row << std::setprecision(10); - for (auto& it : trace_event::instance_snapshot()) - { - std::ostringstream row; - row << std::setprecision(10); - row << it.getName(); + row << it.getName(); - const char* unit_label = it.getUnitLabel(); - if(unit_label[0]) - { - row << "(" << unit_label << ")"; - } + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } - S32 samples = 0; + S32 samples = 0; - for (S32 frame = 1; frame <= frame_count; frame++) - { - Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); - samples += recording.getSampleCount(it); - F64 mean = recording.getMean(it); - if (llisnan(mean)) + for (S32 frame = 1; frame <= frame_count; frame++) { - row << ", n/a"; + Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + row << ", " << recording.getSum(it); } - else + + row << '\n'; + + if (samples > 0) { - row << ", " << mean; + os << row.str(); } } - row << '\n'; + typedef StatType trace_event; - if (samples > 0) + for (auto& it : trace_event::instance_snapshot()) { - os << row.str(); - } - } + std::ostringstream row; + row << std::setprecision(10); + row << it.getName(); - typedef StatType trace_sample; + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } - for (auto& it : trace_sample::instance_snapshot()) - { - std::ostringstream row; - row << std::setprecision(10); - row << it.getName(); + S32 samples = 0; - const char* unit_label = it.getUnitLabel(); - if(unit_label[0]) - { - row << "(" << unit_label << ")"; + for (S32 frame = 1; frame <= frame_count; frame++) + { + Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + F64 mean = recording.getMean(it); + if (llisnan(mean)) + { + row << ", n/a"; + } + else + { + row << ", " << mean; + } + } + + row << '\n'; + + if (samples > 0) + { + os << row.str(); + } } - S32 samples = 0; + typedef StatType trace_sample; - for (S32 frame = 1; frame <= frame_count; frame++) + for (auto& it : trace_sample::instance_snapshot()) { - Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); - samples += recording.getSampleCount(it); - F64 mean = recording.getMean(it); - if (llisnan(mean)) + std::ostringstream row; + row << std::setprecision(10); + row << it.getName(); + + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 1; frame <= frame_count; frame++) { - row << ", n/a"; + Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + F64 mean = recording.getMean(it); + if (llisnan(mean)) + { + row << ", n/a"; + } + else + { + row << ", " << mean; + } } - else + + row << '\n'; + + if (samples > 0) { - row << ", " << mean; + os << row.str(); } } - row << '\n'; - - if (samples > 0) + typedef StatType trace_mem; + for (auto& it : trace_mem::instance_snapshot()) { - os << row.str(); - } - } + os << it.getName() << "(KiB)"; - typedef StatType trace_mem; - for (auto& it : trace_mem::instance_snapshot()) - { - os << it.getName() << "(KiB)"; + for (S32 frame = 1; frame <= frame_count; frame++) + { + os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits(); + } - for (S32 frame = 1; frame <= frame_count; frame++) - { - os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits(); + os << '\n'; } - os << '\n'; + os.flush(); + os.close(); + } + catch (const std::ios_base::failure &e) + { + LL_WARNS() << "Unable to dump scene monitor results: " << e.what() << LL_ENDL; } - - os.flush(); - os.close(); } //------------------------------------------------------------------------------------------------------------- -- cgit v1.2.3 From b36082170e89c40b73e536a2ab8b2dcbe4220806 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 28 Jan 2021 23:30:07 +0200 Subject: SL-14767 Expanded logging to be a bit more informative --- indra/llmessage/llavatarnamecache.cpp | 50 ++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-) (limited to 'indra') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index fbd65cc67b..72db7e816a 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -145,10 +145,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector::const_iterator it = agentIds.begin(); - for ( ; it != agentIds.end(); ++it) + else { - const LLUUID& agent_id = *it; - LLAvatarNameCache::getInstance()->handleAgentError(agent_id); + success = httpResults["success"].asBoolean(); + if (!success) + { + LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code " + << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL; + } } - return; } - LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); + if (LLAvatarNameCache::instanceExists()) + { + if (!success) + { // on any sort of failure add dummy records for any agent IDs + // in this request that we do not have cached already + std::vector::const_iterator it = agentIds.begin(); + for (; it != agentIds.end(); ++it) + { + const LLUUID& agent_id = *it; + LLAvatarNameCache::getInstance()->handleAgentError(agent_id); + } + return; + } + LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); + } } catch (...) { LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName() - << "('" << url << "', " << agentIds.size() - << " http result: " << httpResults.asString() - << " Agent Ids)")); + << "('" << url << "', " + << agentIds.size() << "Agent Ids," + << " http result: " << S32(success) + << " has response: " << S32(httpResults.size()) + << ")")); throw; } } -- cgit v1.2.3 From 6c2c8c62dbd0a8168ba59512d946151465586aec Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 30 Jan 2021 01:23:04 +0200 Subject: SL-14793 Landmark fetching not cleaning request list on completion --- indra/newview/lllandmarklist.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index b4236c406b..543d2a087f 100644 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -107,11 +107,13 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t return NULL; } + mRequestedList[asset_uuid] = gFrameTimeSeconds; + + // Note that getAssetData can callback immediately and cleans mRequestedList gAssetStorage->getAssetData(asset_uuid, LLAssetType::AT_LANDMARK, LLLandmarkList::processGetAssetReply, NULL); - mRequestedList[asset_uuid] = gFrameTimeSeconds; } return NULL; } @@ -194,11 +196,15 @@ void LLLandmarkList::processGetAssetReply( landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin(); LLUUID asset_uuid = *iter; gLandmarkList.mWaitList.erase(iter); + + // add to mRequestedList before calling getAssetData() + gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds; + + // Note that getAssetData can callback immediately and cleans mRequestedList gAssetStorage->getAssetData(asset_uuid, LLAssetType::AT_LANDMARK, LLLandmarkList::processGetAssetReply, NULL); - gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds; } scheduling = false; } -- cgit v1.2.3 From aee03dfe7419d137cbdbd966fd78c80e5f1c7836 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 4 Feb 2021 20:10:45 +0200 Subject: SL-14828 Update web_profile_url for Aditi --- indra/newview/llviewernetwork.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index a593905060..be05ac0d3a 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -130,7 +130,7 @@ void LLGridManager::initialize(const std::string& grid_file) "https://secondlife.aditi.lindenlab.com/helpers/", DEFAULT_LOGIN_PAGE, SL_UPDATE_QUERY_URL, - "https://my.aditi.lindenlab.com/", + "https://my.secondlife-beta.com/", "Aditi"); LLSD other_grids; -- cgit v1.2.3 From af7554a83548a32de69fcbc7c7d4a49c19865183 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 10 Feb 2021 22:30:02 +0200 Subject: SL-11215 Release notes url should be an url --- indra/newview/lllogininstance.cpp | 14 ++++++++++---- indra/newview/skins/default/xui/en/notifications.xml | 3 +++ 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 2427f620de..e81d2cc082 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -58,6 +58,7 @@ #include "llevents.h" #include "llappviewer.h" #include "llsdserialize.h" +#include "lltrans.h" #include #include @@ -364,16 +365,21 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) << LL_ENDL; login_version = vvm_version; } - if (relnotes.empty()) + if (relnotes.empty() || relnotes.find("://") == std::string::npos) { - // I thought this would be available in strings.xml or some such - relnotes = "https://secondlife.com/support/downloads/"; + relnotes = LLTrans::getString("RELEASE_NOTES_BASE_URL"); + if (!LLStringUtil::endsWith(relnotes, "/")) + relnotes += "/"; + relnotes += LLURI::escape(login_version) + ".html"; } if (gViewerWindow) gViewerWindow->setShowProgress(FALSE); - LLSD args(LLSDMap("VERSION", login_version)("URL", relnotes)); + LLSD args; + args["VERSION"] = login_version; + args["URL"] = relnotes; + if (updater.isUndefined()) { // If the updater failed to shake hands, better advise the user to diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 990bf0e93f..107330d618 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4059,6 +4059,7 @@ Please download from https://secondlife.com/support/downloads/ type="alertmodal"> Version [VERSION] is required for login. Release notes: [URL] + Click OK to download and install. confirm Version [VERSION] has been downloaded and is ready to install. Release notes: [URL] + Click OK to install. confirm Version [VERSION] has been downloaded and is ready to install. Release notes: [URL] + Proceed? confirm Date: Thu, 11 Feb 2021 00:32:29 +0200 Subject: SL-11215 Fixed unit test --- indra/newview/tests/lllogininstance_test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra') diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 57f2d31eab..f9abc8b25d 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -41,6 +41,7 @@ #include "../test/lltut.h" #include "llevents.h" #include "llnotificationsutil.h" +#include "lltrans.h" #if defined(LL_WINDOWS) #pragma warning(disable: 4355) // using 'this' in base-class ctor initializer expr @@ -77,6 +78,11 @@ void LLViewerWindow::setShowProgress(BOOL show) {} LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; } LLViewerWindow* gViewerWindow; + +std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string) +{ + return std::string("test_trans"); +} class LLLogin::Impl { -- cgit v1.2.3 From 0e3d8023dc08d6b4965e71064c3ac5a2f1e4f180 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 11 Feb 2021 18:45:57 +0200 Subject: SL-12795 Fix log session name not updating --- indra/newview/llconversationlog.cpp | 3 ++- indra/newview/llconversationlog.h | 2 +- indra/newview/llimview.cpp | 7 +++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'indra') diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index fd59dd2601..a696c99a82 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -398,7 +398,7 @@ void LLConversationLog::deleteBackupLogs() } } -void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::string &expected_filename) +void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name) { conversations_vec_t::iterator conv_it = mConversations.begin(); for (; conv_it != mConversations.end(); ++conv_it) @@ -409,6 +409,7 @@ void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::stri { LLLogChat::renameLogFile(conv_it->getHistoryFileName(), expected_filename); conv_it->updateHistoryFileName(expected_filename); + conv_it->setConversationName(new_session_name); } break; } diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index 82e7e597d0..820a5db491 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -140,7 +140,7 @@ public: */ void cache(); // will check if current name is edentical with the one on disk and will rename the one on disk if it isn't - void verifyFilename(const LLUUID& session_id, const std::string &expected_filename); + void verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name); bool moveLog(const std::string &originDirectory, const std::string &targetDirectory); void getListOfBackupLogs(std::vector& list_of_backup_logs); void deleteBackupLogs(); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index b68fec297a..1059324a16 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -602,10 +602,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& } buildHistoryFileName(); - if (isP2P()) // user's account name can change, but filenames are account name based - { - LLConversationLog::getInstance()->verifyFilename(mSessionID, mHistoryFileName); - } loadHistory(); // Localizing name of ad-hoc session. STORM-153 @@ -973,6 +969,9 @@ void LLIMModel::LLIMSession::buildHistoryFileName() // Incoming P2P sessions include a name that we can use to build a history file name mHistoryFileName = LLCacheName::buildUsername(mName); } + + // user's account name can change, but filenames and session names are account name based + LLConversationLog::getInstance()->verifyFilename(mSessionID, mHistoryFileName, av_name.getCompleteName()); } else if (isGroupChat()) { -- cgit v1.2.3 From ba608514e1f2e7c05706fc3740d64b8390fbdb69 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 1 Mar 2021 17:16:07 +0200 Subject: SL-13609 Don't use any icon for Nearby chat --- indra/newview/llconversationview.cpp | 4 +- indra/newview/llfloaterimsessiontab.cpp | 12 +---- .../skins/default/xui/en/floater_im_session.xml | 57 ++++++++++------------ .../xui/en/panel_conversation_list_item.xml | 56 ++++++++++----------- 4 files changed, 56 insertions(+), 73 deletions(-) (limited to 'indra') diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 71346b4b43..7c9027d1b5 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -249,8 +249,8 @@ BOOL LLConversationViewSession::postBuild() } case LLConversationItem::CONV_SESSION_NEARBY: { - LLIconCtrl* icon = mItemPanel->getChild("nearby_chat_icon"); - icon->setVisible(true); + mItemPanel->getChild("session_icon_panel")->setVisible(false); + mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true); mIsInActiveVoiceChannel = true; if(LLVoiceClient::instanceExists()) diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index e7f428c06a..492f63a700 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -48,7 +48,6 @@ const F32 REFRESH_INTERVAL = 1.0f; const std::string ICN_GROUP("group_chat_icon"); -const std::string ICN_NEARBY("nearby_chat_icon"); const std::string ICN_AVATAR("avatar_icon"); void cb_group_do_nothing() @@ -347,6 +346,8 @@ BOOL LLFloaterIMSessionTab::postBuild() assignResizeLimits(); + getChild("session_icon_layout_panel")->setVisible(mSessionID.notNull()); + return result; } @@ -726,15 +727,6 @@ void LLFloaterIMSessionTab::updateChatIcon(const LLUUID& id) icon->setValue(id); } } - else - { - if (mIsNearbyChat) - { - LLIconCtrl* icon = getChild(ICN_NEARBY); - icon->setVisible(true); - } - } - } void LLFloaterIMSessionTab::hideAllStandardButtons() diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 15f02ab9c3..f61e5f1acc 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -265,38 +265,33 @@ bottom="-1" left="0" right="-1"> + + + + - - - diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml index 4372cf69bf..3be2beb0aa 100644 --- a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml @@ -6,45 +6,41 @@ name="conversation_list_item" mouse_opaque="false" width="120"> - - - + + width="109"> + + + + Date: Wed, 16 Oct 2019 20:31:54 +0100 Subject: SL-12122 - removed frametime spikes in windows build caused by unnecessary call to GetPerformanceInfo() --- indra/llcommon/llsys.cpp | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 1f8d558fbe..eff4dd91ea 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -55,6 +55,7 @@ #include #include #include +#include "llfasttimer.h" using namespace llsd; @@ -925,8 +926,12 @@ LLMemoryInfo& LLMemoryInfo::refresh() return *this; } +static LLTrace::BlockTimerStatHandle FTM_MEMINFO_LOAD_STATS("MemInfo Load Stats"); + LLSD LLMemoryInfo::loadStatsMap() { + LL_RECORD_BLOCK_TIME(FTM_MEMINFO_LOAD_STATS); + // This implementation is derived from stream() code (as of 2011-06-29). Stats stats; @@ -948,24 +953,11 @@ LLSD LLMemoryInfo::loadStatsMap() stats.add("Total Virtual KB", state.ullTotalVirtual/div); stats.add("Avail Virtual KB", state.ullAvailVirtual/div); - PERFORMANCE_INFORMATION perf; - perf.cb = sizeof(perf); - GetPerformanceInfo(&perf, sizeof(perf)); - - SIZE_T pagekb(perf.PageSize/1024); - stats.add("CommitTotal KB", perf.CommitTotal * pagekb); - stats.add("CommitLimit KB", perf.CommitLimit * pagekb); - stats.add("CommitPeak KB", perf.CommitPeak * pagekb); - stats.add("PhysicalTotal KB", perf.PhysicalTotal * pagekb); - stats.add("PhysicalAvail KB", perf.PhysicalAvailable * pagekb); - stats.add("SystemCache KB", perf.SystemCache * pagekb); - stats.add("KernelTotal KB", perf.KernelTotal * pagekb); - stats.add("KernelPaged KB", perf.KernelPaged * pagekb); - stats.add("KernelNonpaged KB", perf.KernelNonpaged * pagekb); - stats.add("PageSize KB", pagekb); - stats.add("HandleCount", perf.HandleCount); - stats.add("ProcessCount", perf.ProcessCount); - stats.add("ThreadCount", perf.ThreadCount); + // SL-12122 - Call to GetPerformanceInfo() was removed here. Took + // on order of 10 ms, causing unacceptable frame time spike every + // second, and results were never used. If this is needed in the + // future, must find a way to avoid frame time impact (e.g. move + // to another thread, call much less often). PROCESS_MEMORY_COUNTERS_EX pmem; pmem.cb = sizeof(pmem); -- cgit v1.2.3 From b0de02aa02b6926805a71f1c1044b65bf894bcc5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 22 Mar 2021 23:45:25 +0200 Subject: SL-14993 Crash accessing mInvBindMatrix --- indra/llprimitive/llmodel.cpp | 30 +++++++++++++++++++----------- indra/newview/llskinningutil.cpp | 34 +++------------------------------- indra/newview/llskinningutil.h | 1 - 3 files changed, 22 insertions(+), 43 deletions(-) (limited to 'indra') diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index a2d9b4cd9b..702a1b5238 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -434,7 +434,7 @@ void LLModel::generateNormals(F32 angle_cutoff) if (vol_face.mNumIndices > 65535) { - LL_WARNS() << "Too many vertices for normal generation to work." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Too many vertices for normal generation to work." << LL_ENDL; continue; } @@ -1100,7 +1100,7 @@ bool LLModel::loadModel(std::istream& is) { if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024)) { - LL_WARNS() << "Mesh header parse error. Not a valid mesh asset!" << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Mesh header parse error. Not a valid mesh asset!" << LL_ENDL; return false; } } @@ -1132,7 +1132,7 @@ bool LLModel::loadModel(std::istream& is) if (header[lod_name[lod]]["offset"].asInteger() == -1 || header[lod_name[lod]]["size"].asInteger() == 0 ) { //cannot load requested LOD - LL_WARNS() << "LoD data is invalid!" << LL_ENDL; + LL_WARNS("MESHSKININFO") << "LoD data is invalid!" << LL_ENDL; return false; } @@ -1195,7 +1195,7 @@ bool LLModel::loadModel(std::istream& is) } else { - LL_WARNS() << "unpackVolumeFaces failed!" << LL_ENDL; + LL_WARNS("MESHSKININFO") << "unpackVolumeFaces failed!" << LL_ENDL; } return false; @@ -1223,7 +1223,7 @@ bool LLModel::isMaterialListSubset( LLModel* ref ) if (!foundRef) { - LL_INFOS() << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL; + LL_INFOS("MESHSKININFO") << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL; return false; } } @@ -1259,7 +1259,7 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn bool isASubset = isMaterialListSubset( ref ); if ( !isASubset ) { - LL_INFOS()<<"Material of model is not a subset of reference."<= face.mNumVertices) { - LL_WARNS() << "Face has invalid index." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Face has invalid index." << LL_ENDL; return false; } } if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0) { - LL_WARNS() << "Face has invalid number of indices." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Face has invalid number of indices." << LL_ENDL; return false; } @@ -1879,7 +1887,7 @@ bool validate_model(const LLModel* mdl) { if (mdl->getNumVolumeFaces() == 0) { - LL_WARNS() << "Model has no faces!" << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Model has no faces!" << LL_ENDL; return false; } @@ -1887,13 +1895,13 @@ bool validate_model(const LLModel* mdl) { if (mdl->getVolumeFace(i).mNumVertices == 0) { - LL_WARNS() << "Face has no vertices." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Face has no vertices." << LL_ENDL; return false; } if (mdl->getVolumeFace(i).mNumIndices == 0) { - LL_WARNS() << "Face has no indices." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Face has no indices." << LL_ENDL; return false; } diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 1fb63c7444..f325315933 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -309,7 +309,8 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a if (vol_face.mJointRiggingInfoTab.needsUpdate()) { S32 num_verts = vol_face.mNumVertices; - if (num_verts>0 && vol_face.mWeights && (skin->mJointNames.size()>0)) + S32 num_joints = skin->mJointNames.size(); + if (num_verts > 0 && vol_face.mWeights && num_joints > 0) { initJointNums(const_cast(skin), avatar); if (vol_face.mJointRiggingInfoTab.size()==0) @@ -343,7 +344,7 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a for (U32 k=0; k<4; ++k) { S32 joint_index = idx[k]; - if (wght[k] > 0.0f) + if (wght[k] > 0.0f && num_joints > joint_index) { S32 joint_num = skin->mJointNums[joint_index]; if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) @@ -394,35 +395,6 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a } } -void LLSkinningUtil::updateRiggingInfo_(LLMeshSkinInfo* skin, LLVOAvatar *avatar, S32 num_verts, LLVector4a* weights, LLVector4a* positions, U8* joint_indices, LLJointRiggingInfoTab &rig_info_tab) -{ - LL_RECORD_BLOCK_TIME(FTM_FACE_RIGGING_INFO); - for (S32 i=0; i < num_verts; i++) - { - LLVector4a& pos = positions[i]; - LLVector4a& wght = weights[i]; - for (U32 k=0; k<4; ++k) - { - S32 joint_num = skin->mJointNums[joint_indices[k]]; - llassert(joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS); - { - rig_info_tab[joint_num].setIsRiggedTo(true); - LLMatrix4a bind_shape; - bind_shape.loadu(skin->mBindShapeMatrix); - LLMatrix4a inv_bind; - inv_bind.loadu(skin->mInvBindMatrix[joint_indices[k]]); - LLMatrix4a mat; - matMul(bind_shape, inv_bind, mat); - LLVector4a pos_joint_space; - mat.affineTransform(pos, pos_joint_space); - pos_joint_space.mul(wght[k]); - LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents(); - update_min_max(extents[0], extents[1], pos_joint_space); - } - } - } -} - // This is used for extracting rotation from a bind shape matrix that // already has scales baked in LLQuaternion LLSkinningUtil::getUnscaledQuaternion(const LLMatrix4& mat4) diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 549aa6a29f..efe7c85997 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -67,7 +67,6 @@ namespace LLSkinningUtil void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar); void updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face); - void updateRiggingInfo_(LLMeshSkinInfo* skin, LLVOAvatar *avatar, S32 num_verts, LLVector4a* weights, LLVector4a* positions, U8* joint_indices, LLJointRiggingInfoTab &rig_info_tab); LLQuaternion getUnscaledQuaternion(const LLMatrix4& mat4); }; -- cgit v1.2.3 From e51ec77431380891b98c40e89edf8f57d90710c4 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 1 Apr 2021 13:47:18 +0300 Subject: SL-15053 Use previous icon for Nearby chat --- indra/newview/llconversationview.cpp | 4 +- indra/newview/llfloaterimsessiontab.cpp | 12 ++++- .../default/textures/icons/nearby_chat_icon.png | Bin 1035 -> 399 bytes .../skins/default/xui/en/floater_im_session.xml | 57 +++++++++++---------- .../xui/en/panel_conversation_list_item.xml | 56 ++++++++++---------- 5 files changed, 73 insertions(+), 56 deletions(-) (limited to 'indra') diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 7c9027d1b5..71346b4b43 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -249,8 +249,8 @@ BOOL LLConversationViewSession::postBuild() } case LLConversationItem::CONV_SESSION_NEARBY: { - mItemPanel->getChild("session_icon_panel")->setVisible(false); - + LLIconCtrl* icon = mItemPanel->getChild("nearby_chat_icon"); + icon->setVisible(true); mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true); mIsInActiveVoiceChannel = true; if(LLVoiceClient::instanceExists()) diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 492f63a700..e7f428c06a 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -48,6 +48,7 @@ const F32 REFRESH_INTERVAL = 1.0f; const std::string ICN_GROUP("group_chat_icon"); +const std::string ICN_NEARBY("nearby_chat_icon"); const std::string ICN_AVATAR("avatar_icon"); void cb_group_do_nothing() @@ -346,8 +347,6 @@ BOOL LLFloaterIMSessionTab::postBuild() assignResizeLimits(); - getChild("session_icon_layout_panel")->setVisible(mSessionID.notNull()); - return result; } @@ -727,6 +726,15 @@ void LLFloaterIMSessionTab::updateChatIcon(const LLUUID& id) icon->setValue(id); } } + else + { + if (mIsNearbyChat) + { + LLIconCtrl* icon = getChild(ICN_NEARBY); + icon->setVisible(true); + } + } + } void LLFloaterIMSessionTab::hideAllStandardButtons() diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png index 2cb577776d..5ac4258b9d 100644 Binary files a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png and b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png differ diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index f61e5f1acc..15f02ab9c3 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -265,33 +265,38 @@ bottom="-1" left="0" right="-1"> - - - - + + + diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml index 3be2beb0aa..4372cf69bf 100644 --- a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml @@ -6,41 +6,45 @@ name="conversation_list_item" mouse_opaque="false" width="120"> - + + + - - - - + width="90"> Date: Wed, 31 Mar 2021 21:45:35 +0300 Subject: SL-15061 Crash deleting non-zero reference in LLConversationItemSession --- indra/newview/llconversationmodel.cpp | 28 ++++++++++++++++++---------- indra/newview/llconversationmodel.h | 2 +- indra/newview/llconversationview.cpp | 9 ++++----- 3 files changed, 23 insertions(+), 16 deletions(-) (limited to 'indra') diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index fbdf08d8aa..4cfde21e32 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -350,16 +350,24 @@ void LLConversationItemSession::clearParticipants() } -void LLConversationItemSession::deleteParticipantModels() -{ - // Make sure that no views exist before use and that view-owned items were removed! - // - // Normally we are not supposed to delete models directly, they should be - // owned by views and this action will result in crashes, but LLParticipantList - // creates models separately from views (it probably shouldn't) and then those - // models wait for idle cycles to be assigned to view. - // this code is meant to delete 'waiting' models - std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); +void LLConversationItemSession::clearAndDeparentModels() +{ + std::for_each(mChildren.begin(), mChildren.end(), + [](LLFolderViewModelItem* c) + { + if (c->getNumRefs() == 0) + { + // LLConversationItemParticipant can be created but not assigned to any view, + // it was waiting for an "add_participant" event to be processed + delete c; + } + else + { + // Model is still assigned to some view/widget + c->setParent(NULL); + } + } + ); mChildren.clear(); } diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index e30bfbb759..787deeb594 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -165,7 +165,7 @@ public: void removeParticipant(LLConversationItemParticipant* participant); void removeParticipant(const LLUUID& participant_id); void clearParticipants(); - void deleteParticipantModels(); // do not use while there are existing participant views + void clearAndDeparentModels(); // will delete unowned models and deparent owned ones LLConversationItemParticipant* findParticipant(const LLUUID& participant_id); void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted); diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 71346b4b43..df16868132 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -108,8 +108,7 @@ void LLConversationViewSession::destroyView() // Chat can create and parent models(listeners) to session's model before creating // coresponding views, such participant's models normally will wait for idle cycles // but since we are deleting session and won't be processing any more events, make - // sure unowned models are removed as well. - // Might be good idea to just have an LLPointer list somewhere in LLConversationItemSession + // sure unowned LLConversationItemParticipant models are removed as well. LLConversationItemSession* vmi = dynamic_cast(getViewModelItem()); @@ -146,9 +145,9 @@ void LLConversationViewSession::destroyView() folderp->destroyView(); } - // Now everything that is left in model(listener) is unowned, - // it is safe to remove - vmi->deleteParticipantModels(); + // Now everything that is left in model(listener) is not owned by views, + // only by sessions, deparent so it won't point to soon to be dead model + vmi->clearAndDeparentModels(); } LLFolderViewFolder::destroyView(); -- cgit v1.2.3 From 4a99fe56d9de421a74fd0d523df455bacbac7afb Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 15 Apr 2021 17:35:43 +0300 Subject: SL-14914 New release viewer install updated to RC unexpectedly Requested behavior: First install of a new viewer should never prompt to update to any RC. Anfortunately neither viewer nor updater can tell the difference betwen RC and optional release update, so setting updater to download only required updates. --- indra/newview/llappviewer.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1a64052ed8..0b2cdff36c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1172,7 +1172,16 @@ bool LLAppViewer::init() // add LEAP mode command-line argument to whichever of these we selected updater.args.add("leap"); // UpdaterServiceSettings - updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting"))); + if (gSavedSettings.getBOOL("FirstLoginThisInstall")) + { + // Befor first login, treat this as 'manual' updates, + // updater won't install anything, but required updates + updater.args.add("0"); + } + else + { + updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting"))); + } // channel updater.args.add(LLVersionInfo::instance().getChannel()); // testok -- cgit v1.2.3 From ce65bc2f13409d75dbc6502c970030cc5ed2e5ad Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 29 Apr 2021 12:26:23 -0400 Subject: Increment viewer version to 6.4.19 following promotion of DRTVWR-515 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index a0b6fce83f..427dc381ad 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.18 +6.4.19 -- cgit v1.2.3