From e72c120e9eb1691abdcf0a3c6e650be68a15b6bb Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 17 May 2017 22:34:50 +0300 Subject: [PATCH 01/13] MAINT-6805 Fixed Right-click menus in the right and left panes of the Conversations windows are different --- indra/newview/llavataractions.cpp | 12 +- indra/newview/llavataractions.h | 5 + indra/newview/llchathistory.cpp | 264 +++++++++++++++++- indra/newview/llfloaterimcontainer.cpp | 22 +- indra/newview/llfloaterimcontainer.h | 1 - .../skins/default/xui/en/menu_avatar_icon.xml | 44 ++- 6 files changed, 306 insertions(+), 42 deletions(-) diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 219d9da01f..8fe684ad79 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -1005,7 +1005,7 @@ void LLAvatarActions::toggleBlock(const LLUUID& id) } // static -void LLAvatarActions::toggleMuteVoice(const LLUUID& id) +void LLAvatarActions::toggleMute(const LLUUID& id, U32 flags) { LLAvatarName av_name; LLAvatarNameCache::get(id, &av_name); @@ -1016,14 +1016,20 @@ void LLAvatarActions::toggleMuteVoice(const LLUUID& id) LLMute mute(id, av_name.getUserName(), LLMute::AGENT); if (!is_muted) { - mute_list->add(mute, LLMute::flagVoiceChat); + mute_list->add(mute, flags); } else { - mute_list->remove(mute, LLMute::flagVoiceChat); + mute_list->remove(mute, flags); } } +// static +void LLAvatarActions::toggleMuteVoice(const LLUUID& id) +{ + toggleMute(id, LLMute::flagVoiceChat); +} + // static bool LLAvatarActions::canOfferTeleport(const LLUUID& id) { diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 256d44d820..b56d5b0fb9 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -130,6 +130,11 @@ public: */ static void toggleBlock(const LLUUID& id); + /** + * Mute/unmute avatar. + */ + static void toggleMute(const LLUUID& id, U32 flags); + /** * Block/unblock the avatar voice. */ diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 9798ef3529..5748eeec47 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -38,10 +38,14 @@ #include "llpanel.h" #include "lluictrlfactory.h" #include "llscrollcontainer.h" -#include "llavatariconctrl.h" -#include "llcallingcard.h" //for LLAvatarTracker +#include "llagent.h" #include "llagentdata.h" #include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llcallingcard.h" //for LLAvatarTracker +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llspeakers.h" //for LLIMSpeakerMgr #include "lltrans.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" @@ -49,7 +53,6 @@ #include "llstylemap.h" #include "llslurl.h" #include "lllayoutstack.h" -#include "llagent.h" #include "llnotificationsutil.h" #include "lltoastnotifypanel.h" #include "lltooltip.h" @@ -61,7 +64,6 @@ #include "llurlaction.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" -#include "llmutelist.h" static LLDefaultChildRegistry::Register r("chat_history"); @@ -187,6 +189,161 @@ public: return false; } + void banGroupMember(const LLUUID& participant_uuid) + { + LLUUID group_uuid = mSessionID; + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid); + if (!gdatap) + { + // Not a group + return; + } + + gdatap->banMemberById(participant_uuid); + } + + bool canBanInGroup() + { + LLUUID group_uuid = mSessionID; + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid); + if (!gdatap) + { + // Not a group + return false; + } + + if (gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER) + && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS)) + { + return true; + } + + return false; + } + + bool canBanGroupMember(const LLUUID& participant_uuid) + { + LLUUID group_uuid = mSessionID; + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid); + if (!gdatap) + { + // Not a group + return false; + } + + if (gdatap->mPendingBanRequest) + { + return false; + } + + if (gAgentID == getAvatarId()) + { + //Don't ban self + return false; + } + + if (gdatap->isRoleMemberDataComplete()) + { + if (gdatap->mMembers.size()) + { + LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(participant_uuid); + if (mi != gdatap->mMembers.end()) + { + LLGroupMemberData* member_data = (*mi).second; + // Is the member an owner? + if (member_data && member_data->isInRole(gdatap->mOwnerRole)) + { + return false; + } + + if (gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER) + && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS)) + { + return true; + } + } + } + } + + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + LLSpeaker * speakerp = speaker_mgr->findSpeaker(participant_uuid).get(); + + if (speakerp + && gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER) + && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS)) + { + return true; + } + } + + return false; + } + + bool isGroupModerator() + { + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (!speaker_mgr) + { + LL_WARNS() << "Speaker manager is missing" << LL_ENDL; + return false; + } + + // Is session a group call/chat? + if(gAgent.isInGroup(mSessionID)) + { + LLSpeaker * speakerp = speaker_mgr->findSpeaker(gAgentID).get(); + + // Is agent a moderator? + return speakerp && speakerp->mIsModerator; + } + + return false; + } + + bool canModerate(const std::string& userdata) + { + // only group moderators can perform actions related to this "enable callback" + if (!isGroupModerator() || gAgentID == getAvatarId()) + { + return false; + } + + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (!speaker_mgr) + { + return false; + } + + LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get(); + if (!speakerp) + { + return false; + } + + bool voice_channel = speakerp->isInVoiceChannel(); + + if ("can_moderate_voice" == userdata) + { + return voice_channel; + } + else if ("can_mute" == userdata) + { + return voice_channel && (speakerp->mStatus != LLSpeaker::STATUS_MUTED); + } + else if ("can_unmute" == userdata) + { + return speakerp->mStatus == LLSpeaker::STATUS_MUTED; + } + else if ("can_allow_text_chat" == userdata) + { + return true; + } + + return false; + } + void onAvatarIconContextMenuItemClicked(const LLSD& userdata) { std::string level = userdata.asString(); @@ -245,11 +402,36 @@ public: } else if(level == "block_unblock") { - mute(getAvatarId(), LLMute::flagVoiceChat); + LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat); } else if(level == "mute_unmute") { - mute(getAvatarId(), LLMute::flagTextChat); + LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagTextChat); + } + else if(level == "toggle_allow_text_chat") + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + speaker_mgr->toggleAllowTextChat(getAvatarId()); + } + else if(level == "group_mute") + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->moderateVoiceParticipant(getAvatarId(), false); + } + } + else if(level == "group_unmute") + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->moderateVoiceParticipant(getAvatarId(), true); + } + } + else if(level == "ban_member") + { + banGroupMember(getAvatarId()); } } @@ -265,24 +447,69 @@ public: { return LLMuteList::getInstance()->isMuted(getAvatarId(), LLMute::flagTextChat); } + else if (level == "is_allowed_text_chat") + { + if (gAgent.isInGroup(mSessionID)) + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + const LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()); + + if (NULL != speakerp) + { + return !speakerp->mModeratorMutedText; + } + } + return false; + } return false; } - void mute(const LLUUID& participant_id, U32 flags) + bool onAvatarIconContextMenuItemEnabled(const LLSD& userdata) { - BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags); - LLAvatarName av_name; - LLAvatarNameCache::get(participant_id, &av_name); - LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT); + std::string level = userdata.asString(); - if (!is_muted) + if (level == "can_allow_text_chat" || level == "can_mute" || level == "can_unmute") { - LLMuteList::getInstance()->add(mute, flags); + return canModerate(userdata); } - else + else if (level == "can_ban_member") { - LLMuteList::getInstance()->remove(mute, flags); + return canBanGroupMember(getAvatarId()); } + return false; + } + + bool onAvatarIconContextMenuItemVisible(const LLSD& userdata) + { + std::string level = userdata.asString(); + + if (level == "show_mute") + { + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get(); + if (speakerp) + { + return speakerp->isInVoiceChannel() && speakerp->mStatus != LLSpeaker::STATUS_MUTED; + } + } + return false; + } + else if (level == "show_unmute") + { + LLSpeakerMgr * speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()).get(); + if (speakerp) + { + return speakerp->mStatus == LLSpeaker::STATUS_MUTED; + } + } + return false; + } + return false; } BOOL postBuild() @@ -292,6 +519,8 @@ public: registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2)); registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2)); + registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2)); + registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2)); registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2)); registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2)); @@ -567,9 +796,14 @@ protected: if(menu) { bool is_friend = LLAvatarActions::isFriend(mAvatarID); + bool is_group_session = gAgent.isInGroup(mSessionID); menu->setItemEnabled("Add Friend", !is_friend); menu->setItemEnabled("Remove Friend", is_friend); + menu->setItemVisible("Moderator Options Separator", is_group_session && isGroupModerator()); + menu->setItemVisible("Moderator Options", is_group_session && isGroupModerator()); + menu->setItemVisible("Group Ban Separator", is_group_session && canBanInGroup()); + menu->setItemVisible("BanMember", is_group_session && canBanInGroup()); if(gAgentID == mAvatarID) { diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 3522932d03..333765f99f 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1150,11 +1150,11 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec } else if ("block_unblock" == command) { - toggleMute(userID, LLMute::flagVoiceChat); + LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat); } else if ("mute_unmute" == command) { - toggleMute(userID, LLMute::flagTextChat); + LLAvatarActions::toggleMute(userID, LLMute::flagTextChat); } else if ("selected" == command || "mute_all" == command || "unmute_all" == command) { @@ -2096,24 +2096,6 @@ void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid) } } -void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags) -{ - BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags); - - LLAvatarName av_name; - LLAvatarNameCache::get(participant_id, &av_name); - LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT); - - if (!is_muted) - { - LLMuteList::getInstance()->add(mute, flags); - } - else - { - LLMuteList::getInstance()->remove(mute, flags); - } -} - void LLFloaterIMContainer::openNearbyChat() { // If there's only one conversation in the container and that conversation is the nearby chat diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 60cef83d9a..90fc0c2bdd 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -176,7 +176,6 @@ private: void moderateVoiceAllParticipants(bool unmute); void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute); void toggleAllowTextChat(const LLUUID& participant_uuid); - void toggleMute(const LLUUID& participant_id, U32 flags); void banSelectedMember(const LLUUID& participant_uuid); void openNearbyChat(); bool isParticipantListExpanded(); diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml index 410caa7290..05ab4d35a0 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml @@ -1,5 +1,5 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + From c7d7728e4a4caadac1875856d77b752bc36a2f56 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 19 May 2017 17:46:08 +0300 Subject: [PATCH 02/13] MAINT-7417 FIXED Confirmation is not shown when removing your own object inworld --- indra/newview/llviewermessage.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 507087d1ae..2dc219a769 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1222,6 +1222,11 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam const LLUUID& obj_id = (*obj_iter); if(!highlight_offered_object(obj_id)) { + const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(obj_id); + if (parent && (parent->getPreferredType() == LLFolderType::FT_TRASH)) + { + gInventory.checkTrashOverflow(); + } continue; } From ed249c13af3509645089b280d3a594c29c216f68 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 19 May 2017 17:50:17 +0300 Subject: [PATCH 03/13] MAINT-7383 Show correct number of items including folder descendants --- indra/newview/llinventorymodel.h | 1 - indra/newview/llinventorypanel.cpp | 11 ++++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index c558c0803b..da78a057b5 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -265,7 +265,6 @@ public: // Follow parent chain to the top. bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; -private: U32 getDescendentsCountRecursive(const LLUUID& id, U32 max_item_limit); //-------------------------------------------------------------------- diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 4b117941a0..5a7881fe49 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1217,7 +1217,16 @@ void LLInventoryPanel::purgeSelectedItems() const std::set inventory_selected = mFolderRoot.get()->getSelectionList(); if (inventory_selected.empty()) return; LLSD args; - args["COUNT"] = (S32)inventory_selected.size(); + S32 count = inventory_selected.size(); + static const U32 trash_max_capacity = gSavedSettings.getU32("InventoryTrashMaxCapacity"); + for (std::set::const_iterator it = inventory_selected.begin(), end_it = inventory_selected.end(); + it != end_it; + ++it) + { + LLUUID item_id = static_cast((*it)->getViewModelItem())->getUUID(); + count += gInventory.getDescendentsCountRecursive(item_id, trash_max_capacity); + } + args["COUNT"] = count; LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(&LLInventoryPanel::callbackPurgeSelectedItems, this, _1, _2)); } From c7dde30435c578b8fd4606135193e3ec8d31bd76 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 19 May 2017 18:47:20 +0300 Subject: [PATCH 04/13] MAINT-7424 Fixed number of items in the Trash not calculating correctly --- indra/newview/llinventorymodel.cpp | 38 ++++++++++++++---------------- indra/newview/llinventorymodel.h | 2 -- indra/newview/llinventorypanel.cpp | 5 +++- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e5fd126d53..7ee41140f0 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -799,22 +799,6 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, } } -U32 LLInventoryModel::getDescendentsCountRecursive(const LLUUID& id, U32 max_item_limit) -{ - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - gInventory.collectDescendents(id, cats, items, LLInventoryModel::INCLUDE_TRASH); - - U32 items_found = items.size() + cats.size(); - - for (U32 i = 0; i < cats.size() && items_found <= max_item_limit; ++i) - { - items_found += getDescendentsCountRecursive(cats[i]->getUUID(), max_item_limit - items_found); - } - - return items_found; -} - void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask) { const LLInventoryObject *obj = getObject(object_id); @@ -3321,9 +3305,12 @@ void LLInventoryModel::emptyFolderType(const std::string notification, LLFolderT LLSD args; if(LLFolderType::FT_TRASH == preferred_type) { - static const U32 trash_max_capacity = gSavedSettings.getU32("InventoryTrashMaxCapacity"); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; const LLUUID trash_id = findCategoryUUIDForType(preferred_type); - args["COUNT"] = (S32)getDescendentsCountRecursive(trash_id, trash_max_capacity); + gInventory.collectDescendents(trash_id, cats, items, LLInventoryModel::INCLUDE_TRASH); //All descendants + S32 item_count = items.size() + cats.size(); + args["COUNT"] = item_count; } LLNotificationsUtil::add(notification, args, LLSD(), boost::bind(&LLInventoryModel::callbackEmptyFolderType, this, _1, _2, preferred_type)); @@ -3433,9 +3420,20 @@ bool callback_preview_trash_folder(const LLSD& notification, const LLSD& respons void LLInventoryModel::checkTrashOverflow() { - static const U32 trash_max_capacity = gSavedSettings.getU32("InventoryTrashMaxCapacity"); + static LLCachedControl trash_max_capacity(gSavedSettings, "InventoryTrashMaxCapacity"); + + // Collect all descendants including those in subfolders. + // + // Note: Do we really need content of subfolders? + // This was made to prevent download of trash folder timeouting + // viewer and sub-folders are supposed to download independently. + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (getDescendentsCountRecursive(trash_id, trash_max_capacity) >= trash_max_capacity) + gInventory.collectDescendents(trash_id, cats, items, LLInventoryModel::INCLUDE_TRASH); + S32 item_count = items.size() + cats.size(); + + if (item_count >= trash_max_capacity) { if (LLFloaterPreviewTrash::isVisible()) { diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index da78a057b5..01e0ed7e9b 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -265,8 +265,6 @@ public: // Follow parent chain to the top. bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; - U32 getDescendentsCountRecursive(const LLUUID& id, U32 max_item_limit); - //-------------------------------------------------------------------- // Find //-------------------------------------------------------------------- diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 5a7881fe49..ba2dce1f98 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1224,7 +1224,10 @@ void LLInventoryPanel::purgeSelectedItems() ++it) { LLUUID item_id = static_cast((*it)->getViewModelItem())->getUUID(); - count += gInventory.getDescendentsCountRecursive(item_id, trash_max_capacity); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(item_id, cats, items, LLInventoryModel::INCLUDE_TRASH); + count += items.size() + cats.size(); } args["COUNT"] = count; LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(&LLInventoryPanel::callbackPurgeSelectedItems, this, _1, _2)); From c9f9e93889ae7400f242db6cc3b01469532c1def Mon Sep 17 00:00:00 2001 From: username = daianakproductengine Date: Fri, 19 May 2017 20:28:59 +0300 Subject: [PATCH 05/13] MAINT-2060 Fixed Double Freeze when clicking on Help>About Second Life --- indra/llwindow/lldxhardware.cpp | 155 ++++++++++++++++++++++++++++++++ indra/llwindow/lldxhardware.h | 2 + indra/newview/llappviewer.cpp | 15 +++- 3 files changed, 169 insertions(+), 3 deletions(-) diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index e7afef63f8..d4790f9f29 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -35,6 +35,7 @@ #undef INITGUID #include +#include #include @@ -206,6 +207,160 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam ) return E_FAIL; } +//Getting the version of graphics controller driver via WMI +std::string LLDXHardware::getDriverVersionWMI() +{ + std::string mDriverVersion; + HRESULT hrCoInitialize = S_OK; + HRESULT hres; + hrCoInitialize = CoInitialize(0); + IWbemLocator *pLoc = NULL; + + hres = CoCreateInstance( + CLSID_WbemLocator, + 0, + CLSCTX_INPROC_SERVER, + IID_IWbemLocator, (LPVOID *)&pLoc); + + if (FAILED(hres)) + { + LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x" << hres << LL_ENDL; + return std::string(); // Program has failed. + } + + IWbemServices *pSvc = NULL; + + // Connect to the root\cimv2 namespace with + // the current user and obtain pointer pSvc + // to make IWbemServices calls. + hres = pLoc->ConnectServer( + _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace + NULL, // User name. NULL = current user + NULL, // User password. NULL = current + 0, // Locale. NULL indicates current + NULL, // Security flags. + 0, // Authority (e.g. Kerberos) + 0, // Context object + &pSvc // pointer to IWbemServices proxy + ); + + if (FAILED(hres)) + { + LL_WARNS("AppInit") << "Could not connect. Error code = 0x" << hres << LL_ENDL; + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + + LL_DEBUGS("AppInit") << "Connected to ROOT\\CIMV2 WMI namespace" << LL_ENDL; + + // Set security levels on the proxy ------------------------- + hres = CoSetProxyBlanket( + pSvc, // Indicates the proxy to set + RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx + RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx + NULL, // Server principal name + RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx + RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx + NULL, // client identity + EOAC_NONE // proxy capabilities + ); + + if (FAILED(hres)) + { + LL_WARNS("AppInit") << "Could not set proxy blanket. Error code = 0x" << hres << LL_ENDL; + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + IEnumWbemClassObject* pEnumerator = NULL; + + // Get the data from the query + ULONG uReturn = 0; + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT * FROM Win32_VideoController"), //Consider using Availability to filter out disabled controllers + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator); + + if (FAILED(hres)) + { + LL_WARNS("AppInit") << "Query for operating system name failed." << " Error code = 0x" << hres << LL_ENDL; + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + + while (pEnumerator) + { + IWbemClassObject *pclsObj = NULL; + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, + &pclsObj, &uReturn); + + if (0 == uReturn) + { + break; // If quantity less then 1. + } + + VARIANT vtProp; + + // Get the value of the Name property + hr = pclsObj->Get(L"DriverVersion", 0, &vtProp, 0, 0); + + if (FAILED(hr)) + { + LL_WARNS("AppInit") << "Query for name property failed." << " Error code = 0x" << hr << LL_ENDL; + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + + // use characters in the returned driver version + BSTR driverVersion(vtProp.bstrVal); + + //convert BSTR to std::string + std::wstring ws(driverVersion, SysStringLen(driverVersion)); + std::string str(ws.begin(), ws.end()); + LL_INFOS("AppInit") << " DriverVersion : " << str << LL_ENDL; + + if (mDriverVersion.empty()) + { + mDriverVersion = str; + } + else if (mDriverVersion != str) + { + LL_WARNS("DriverVersion") << "Different versions of drivers. Version of second driver : " << str << LL_ENDL; + } + + VariantClear(&vtProp); + pclsObj->Release(); + } + + // Cleanup + // ======== + if (pSvc) + { + pSvc->Release(); + } + if (pLoc) + { + pLoc->Release(); + } + if (pEnumerator) + { + pEnumerator->Release(); + } + if (SUCCEEDED(hrCoInitialize)) + { + CoUninitialize(); + } + return mDriverVersion; +} + void get_wstring(IDxDiagContainer* containerp, WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize) { HRESULT hr; diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h index 61a32bf0fb..cf33db8b37 100644 --- a/indra/llwindow/lldxhardware.h +++ b/indra/llwindow/lldxhardware.h @@ -88,6 +88,8 @@ public: // vram_only TRUE does a "light" probe. BOOL getInfo(BOOL vram_only); + std::string getDriverVersionWMI(); + S32 getVRAM() const { return mVRAM; } LLSD getDisplayInfo(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f53ba01d37..4095f1c8ef 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3347,10 +3347,19 @@ LLSD LLAppViewer::getViewerInfo() const info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER)); #if LL_WINDOWS - LLSD driver_info = gDXHardware.getDisplayInfo(); - if (driver_info.has("DriverVersion")) + std::string drvinfo = gDXHardware.getDriverVersionWMI(); + if (!drvinfo.empty()) { - info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"]; + info["GRAPHICS_DRIVER_VERSION"] = drvinfo; + } + else + { + LL_WARNS("Driver version")<< "Cannot get driver version from getDriverVersionWMI" << LL_ENDL; + LLSD driver_info = gDXHardware.getDisplayInfo(); + if (driver_info.has("DriverVersion")) + { + info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"]; + } } #endif From c102bcf0adc45f855f103831542b019ad60702e7 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 22 May 2017 11:44:41 +0300 Subject: [PATCH 06/13] build fix --- indra/newview/llinventorypanel.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index ba2dce1f98..f9c91312ee 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1218,7 +1218,6 @@ void LLInventoryPanel::purgeSelectedItems() if (inventory_selected.empty()) return; LLSD args; S32 count = inventory_selected.size(); - static const U32 trash_max_capacity = gSavedSettings.getU32("InventoryTrashMaxCapacity"); for (std::set::const_iterator it = inventory_selected.begin(), end_it = inventory_selected.end(); it != end_it; ++it) From f34bee596641318d7480acf624e04af7d8bc8bfc Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 22 May 2017 16:45:33 +0300 Subject: [PATCH 07/13] MAINT-1094 FIXED after triggering a menu with control-F10, clicking in-world should move keyboard focus in-world --- indra/llui/llmenugl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 022f814bbc..0d42f726fa 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3331,6 +3331,7 @@ BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask) if (getHighlightedItem()) { clearHoverItem(); + LLMenuGL::setKeyboardMode(FALSE); } else { @@ -3777,10 +3778,10 @@ BOOL LLMenuHolderGL::hideMenus() { return FALSE; } + LLMenuGL::setKeyboardMode(FALSE); BOOL menu_visible = hasVisibleMenu(); if (menu_visible) { - LLMenuGL::setKeyboardMode(FALSE); // clicked off of menu, hide them all for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { From c33fb844ab87c85d8989ea909423b559d417b250 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Tue, 23 May 2017 06:36:16 +0300 Subject: [PATCH 08/13] MAINT-7396 [JigglyPuff] Agent that is not estate owner or estate manager shouldn't be able to toggle estate access settings. --- indra/newview/llfloaterregioninfo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index c33dee5fb4..1af2c10a33 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2296,7 +2296,7 @@ BOOL LLPanelEstateInfo::postBuild() void LLPanelEstateInfo::refresh() { // Disable access restriction controls if they make no sense. - bool public_access = getChild("externally_visible_radio")->getSelectedIndex(); + bool public_access = ("estate_public_access" == getChild("externally_visible_radio")->getValue().asString()); getChildView("Only Allow")->setEnabled(public_access); getChildView("limit_payment")->setEnabled(public_access); @@ -2317,7 +2317,7 @@ void LLPanelEstateInfo::refreshFromEstate() getChild("estate_name")->setValue(estate_info.getName()); setOwnerName(LLSLURL("agent", estate_info.getOwnerID(), "inspect").getSLURLString()); - getChild("externally_visible_radio")->setSelectedIndex(estate_info.getIsExternallyVisible() ? 1 : 0); + getChild("externally_visible_radio")->setValue(estate_info.getIsExternallyVisible() ? "estate_public_access" : "estate_restricted_access"); getChild("voice_chat_check")->setValue(estate_info.getAllowVoiceChat()); getChild("allow_direct_teleport")->setValue(estate_info.getAllowDirectTeleport()); getChild("limit_payment")->setValue(estate_info.getDenyAnonymous()); @@ -2360,7 +2360,7 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con // update model estate_info.setUseFixedSun(false); // we don't support fixed sun estates anymore - estate_info.setIsExternallyVisible(getChild("externally_visible_radio")->getSelectedIndex()); + estate_info.setIsExternallyVisible("estate_public_access" == getChild("externally_visible_radio")->getValue().asString()); estate_info.setAllowDirectTeleport(getChild("allow_direct_teleport")->getValue().asBoolean()); estate_info.setDenyAnonymous(getChild("limit_payment")->getValue().asBoolean()); estate_info.setDenyAgeUnverified(getChild("limit_age_verified")->getValue().asBoolean()); From b4e54352171f6b95714270909cda99dc1c5ad3f0 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 24 May 2017 11:06:21 +0300 Subject: [PATCH 09/13] MAINT-7434 FIXED SLURL instead of username appears in "have said something new" text for some messages --- indra/newview/llnotificationhandler.h | 2 ++ indra/newview/llnotificationhandlerutil.cpp | 14 ++++++++++++++ indra/newview/llnotificationtiphandler.cpp | 2 +- indra/newview/llviewermessage.cpp | 1 + 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 7a183cb298..52c5234137 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -322,6 +322,8 @@ public: */ static std::string getSubstitutionName(const LLNotificationPtr& notification); + static std::string getSubstitutionOriginalName(const LLNotificationPtr& notification); + /** * Adds notification panel to the IM floater. */ diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 4a3923ef6e..6a58196760 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -241,6 +241,20 @@ std::string LLHandlerUtil::getSubstitutionName(const LLNotificationPtr& notifica return res; } +// static +std::string LLHandlerUtil::getSubstitutionOriginalName(const LLNotificationPtr& notification) +{ + if(notification->getSubstitutions().has("ORIGINAL_NAME")) + { + std::string name = notification->getSubstitutions()["ORIGINAL_NAME"]; + if(!name.empty()) + { + return name; + } + } + return LLHandlerUtil::getSubstitutionName(notification); +} + // static void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification) { diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index 596327e8f1..a6ef130cd0 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -86,7 +86,7 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification) } std::string session_name = notification->getPayload()["SESSION_NAME"]; - const std::string name = notification->getSubstitutions()["NAME"]; + const std::string name = LLHandlerUtil::getSubstitutionOriginalName(notification); if (session_name.empty()) { session_name = name; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 2dc219a769..06f868dc08 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2841,6 +2841,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_INVENTORY_ACCEPTED: { args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();; + args["ORIGINAL_NAME"] = original_name; LLSD payload; payload["from_id"] = from_id; // Passing the "SESSION_NAME" to use it for IM notification logging From 5db0af5327e1aa21f607c51cf9e69e3733395350 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 22 May 2017 20:24:45 +0300 Subject: [PATCH 10/13] MAINT-7419 Workaround for some purge and trash issues, stuck descendants count --- indra/newview/llaisapi.cpp | 45 ++++++++++++++++++++++- indra/newview/llinventorybridge.cpp | 8 +++- indra/newview/llpanelmaininventory.cpp | 4 +- indra/newview/llplacesinventorybridge.cpp | 2 +- indra/newview/llviewerinventory.cpp | 8 ++++ 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 648212177b..ee49125711 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -394,6 +394,40 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht { status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"); } + else if (status.getType() == 410) //GONE + { + // Item does not exist or was already deleted from server. + // parent folder is out of sync + if (type == REMOVECATEGORY) + { + LLViewerInventoryCategory *cat = gInventory.getCategory(targetId); + if (cat) + { + LL_WARNS("Inventory") << "Purge failed for '" << cat->getName() + << "' local version:" << cat->getVersion() + << " since folder no longer exists at server. Descendent count: server == " << cat->getDescendentCount() + << ", viewer == " << cat->getViewerDescendentCount() + << LL_ENDL; + gInventory.fetchDescendentsOf(cat->getParentUUID()); + // Note: don't delete folder here - contained items will be deparented (or deleted) + // and since we are clearly out of sync we can't be sure we won't get rid of something we need. + // For example folder could have been moved or renamed with items intact, let it fetch first. + } + } + else if (type == REMOVEITEM) + { + LLViewerInventoryItem *item = gInventory.getItem(targetId); + if (item) + { + LL_WARNS("Inventory") << "Purge failed for '" << item->getName() + << "' since item no longer exists at server." << LL_ENDL; + gInventory.fetchDescendentsOf(item->getParentUUID()); + // since item not on the server and exists at viewer, so it needs an update at the least, + // so delete it, in worst case item will be refetched with new params. + gInventory.onObjectDeletedFromServer(targetId); + } + } + } LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; } @@ -970,7 +1004,16 @@ void AISUpdate::doUpdate() // inventory COF is maintained on the viewer through calls to // LLInventoryModel::accountForUpdate when a changing operation // is performed. This occasionally gets out of sync however. - cat->setVersion(version); + if (version != LLViewerInventoryCategory::VERSION_UNKNOWN) + { + cat->setVersion(version); + } + else + { + // We do not account for update if version is UNKNOWN, so we shouldn't rise version + // either or viewer will get stuck on descendants count -1, try to refetch folder instead + cat->fetch(); + } } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 1b32fc9dfe..c8a20c9d97 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3884,8 +3884,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items LLInventoryModel::cat_array_t* cat_array; LLInventoryModel::item_array_t* item_array; gInventory.getDirectDescendentsOf(mUUID, cat_array, item_array); + LLViewerInventoryCategory *trash = getCategory(); // Enable Empty menu item only when there is something to act upon. - if ((0 == cat_array->size() && 0 == item_array->size()) || is_recent_panel) + // Also don't enable menu if folder isn't fully fetched + if ((0 == cat_array->size() && 0 == item_array->size()) + || is_recent_panel + || !trash + || trash->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN + || trash->getDescendentCount() == LLViewerInventoryCategory::VERSION_UNKNOWN) { disabled_items.push_back(std::string("Empty Trash")); } diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 3db9500de0..dd75ae9c06 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1287,13 +1287,13 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) { const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id); - return children != LLInventoryModel::CHILDREN_NO; + return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id); } if (command_name == "empty_lostnfound") { const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id); - return children != LLInventoryModel::CHILDREN_NO; + return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id); } return TRUE; diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp index 55cb7d616b..471e1c24f3 100644 --- a/indra/newview/llplacesinventorybridge.cpp +++ b/indra/newview/llplacesinventorybridge.cpp @@ -62,7 +62,7 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) + if (!isItemRemovable() || (gInventory.getCategory(mUUID) && !gInventory.isCategoryComplete(mUUID))) { disabled_items.push_back(std::string("Purge Item")); } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index bf79a0595c..da6b18bb77 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1463,6 +1463,10 @@ void remove_inventory_category( LLPointer obj = gInventory.getCategory(cat_id); if(obj) { + if (!gInventory.isCategoryComplete(cat_id)) + { + LL_WARNS() << "Removing (purging) incomplete category " << obj->getName() << LL_ENDL; + } if(LLFolderType::lookupIsProtectedType(obj->getPreferredType())) { LLNotificationsUtil::add("CannotRemoveProtectedCategories"); @@ -1540,6 +1544,10 @@ void purge_descendents_of(const LLUUID& id, LLPointer cb) { if (AISAPI::isAvailable()) { + if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) + { + LL_WARNS() << "Purging not fetched folder: " << cat->getName() << LL_ENDL; + } AISAPI::completion_t cr = (cb) ? boost::bind(&doInventoryCb, cb, _1) : AISAPI::completion_t(); AISAPI::PurgeDescendents(id, cr); } From 7021f95b5b09951d834cfb757b3b842313f27d49 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 24 May 2017 17:28:30 +0300 Subject: [PATCH 11/13] MAINT-7436 FIXED [viewer-neko] Crash occurs when trying to highlight non-existent(or removed item) using SLURI --- indra/newview/llinventorymodel.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 7ee41140f0..0ccaa1992d 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -221,7 +221,11 @@ BOOL LLInventoryModel::isObjectDescendentOf(const LLUUID& obj_id, const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(const LLUUID& obj_id) const { const LLInventoryObject* obj = getObject(obj_id); - + if(!obj) + { + LL_WARNS(LOG_INV) << "Non-existent object [ id: " << obj_id << " ] " << LL_ENDL; + return NULL; + } // Search up the parent chain until we get to root or an acceptable folder. // This assumes there are no cycles in the tree else we'll get a hang. LLUUID parent_id = obj->getParentUUID(); From 561cee12d8d3c456d71efae3b711dbf5115c66f5 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 25 May 2017 16:51:45 +0300 Subject: [PATCH 12/13] MAINT-2585 Make permission request notifications permanent until action taken --- indra/llui/llnotifications.cpp | 6 ++++++ indra/llui/llnotifications.h | 1 + indra/llui/llnotificationtemplate.h | 3 +++ indra/newview/llnotificationofferhandler.cpp | 1 + indra/newview/llnotificationscripthandler.cpp | 1 + indra/newview/skins/default/xui/en/notifications.xml | 3 +++ 6 files changed, 15 insertions(+) diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 604092d536..c364c4d5ae 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -426,6 +426,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par mLogToChat(p.log_to_chat), mLogToIM(p.log_to_im), mShowToast(p.show_toast), + mFadeToast(p.fade_toast), mSoundName("") { if (p.sound.isProvided() @@ -942,6 +943,11 @@ bool LLNotification::canShowToast() const return mTemplatep->mShowToast; } +bool LLNotification::canFadeToast() const +{ + return mTemplatep->mFadeToast; +} + bool LLNotification::hasFormElements() const { return mTemplatep->mForm->getNumElements() != 0; diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 024332ee65..4a701d0ca7 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -558,6 +558,7 @@ public: bool canLogToChat() const; bool canLogToIM() const; bool canShowToast() const; + bool canFadeToast() const; bool hasFormElements() const; void playSound(); diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index bed29254d8..20cbc89ede 100644 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -177,6 +177,7 @@ struct LLNotificationTemplate Optional persist, log_to_im, show_toast, + fade_toast, log_to_chat, force_urls_external; Optional functor, @@ -199,6 +200,7 @@ struct LLNotificationTemplate Params() : name("name"), persist("persist", false), + fade_toast("fade_toast", true), log_to_im("log_to_im", false), show_toast("show_toast", true), log_to_chat("log_to_chat", true), @@ -316,6 +318,7 @@ struct LLNotificationTemplate bool mLogToChat; bool mLogToIM; bool mShowToast; + bool mFadeToast; }; #endif //LL_LLNOTIFICATION_TEMPLATE_H diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 63ab88da42..14d25d8158 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -131,6 +131,7 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) // we not save offer notifications to the syswell floater that should be added to the IM floater p.can_be_stored = !add_notif_to_im; p.force_show = notification->getOfferFromAgent(); + p.can_fade = notification->canFadeToast(); LLScreenChannel* channel = dynamic_cast(mChannel.get()); if(channel) diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index 7acb2f9e90..fef0631fa6 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -77,6 +77,7 @@ void LLScriptHandler::addToastWithNotification(const LLNotificationPtr& notifica p.notification = notification; p.panel = notify_box; p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1); + p.can_fade = notification->canFadeToast(); if(gAgent.isDoNotDisturb()) { p.force_show = notification->getName() == "SystemMessage" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 8620c09f9a..91f3b7456f 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -7527,6 +7527,7 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th name="TeleportOffered" log_to_im="true" log_to_chat="false" + fade_toast="false" type="offer" sound="UISndNewIncomingIMSession"> [NAME_SLURL] has offered to teleport you to their location: @@ -7602,6 +7603,7 @@ However, this region contains content accessible to adults only. icon="notify.tga" name="TeleportRequest" log_to_im="true" + fade_toast="false" type="offer"> [NAME_SLURL] is requesting to be teleported to your location. [MESSAGE] @@ -7958,6 +7960,7 @@ Other Key Experiences may be available. icon="notify.tga" name="ScriptQuestionExperience" persist="false" + fade_toast="false" type="notify"> '<nolink>[OBJECTNAME]</nolink>', an object owned by '[NAME]', requests your participation in the [GRID_WIDE] experience: From bb8609fa9408f206142b5c67983c7d0fd1876b19 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 25 May 2017 18:09:52 +0300 Subject: [PATCH 13/13] MAINT-5100 Fixed viewer not finding sky files at login --- indra/llvfs/lldiriterator.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/llvfs/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp index 76296ff877..3eb64e69d9 100644 --- a/indra/llvfs/lldiriterator.cpp +++ b/indra/llvfs/lldiriterator.cpp @@ -51,7 +51,11 @@ private: LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask) : mIsValid(false) { +#ifdef LL_WINDOWS // or BOOST_WINDOWS_API + fs::path dir_path(utf8str_to_utf16str(dirname)); +#else fs::path dir_path(dirname); +#endif bool is_dir = false;