Merge viewer-neko

meow-7.2.2
Ansariel 2017-05-25 22:49:53 +02:00
commit 099d988fe2
26 changed files with 577 additions and 61 deletions

View File

@ -3353,6 +3353,7 @@ BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask)
if (getHighlightedItem())
{
clearHoverItem();
LLMenuGL::setKeyboardMode(FALSE);
}
else
{
@ -3799,10 +3800,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)
{

View File

@ -427,6 +427,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() && LLUI::sSettingGroups["config"]
@ -950,6 +951,11 @@ bool LLNotification::canShowToast() const
return mTemplatep->mShowToast;
}
bool LLNotification::canFadeToast() const
{
return mTemplatep->mFadeToast;
}
bool LLNotification::hasFormElements() const
{
return mTemplatep->mForm->getNumElements() != 0;

View File

@ -564,6 +564,7 @@ public:
bool canLogToChat() const;
bool canLogToIM() const;
bool canShowToast() const;
bool canFadeToast() const;
bool hasFormElements() const;
void playSound();

View File

@ -177,6 +177,7 @@ struct LLNotificationTemplate
Optional<bool> persist,
log_to_im,
show_toast,
fade_toast,
log_to_chat,
force_urls_external;
Optional<std::string> 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

View File

@ -51,16 +51,11 @@ private:
LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
: mIsValid(false)
{
// <FS:ND> Unicode path on Windows need some extra handling
// fs::path dir_path(dirname);
#ifdef LL_WINDOWS
fs::path dir_path( utf8str_to_utf16str(dirname) );
#ifdef LL_WINDOWS // or BOOST_WINDOWS_API
fs::path dir_path(utf8str_to_utf16str(dirname));
#else
fs::path dir_path(dirname);
#endif
// </FS:ND>
#endif
bool is_dir = false;

View File

@ -35,6 +35,7 @@
#undef INITGUID
#include <wbemidl.h>
#include <comdef.h>
#include <boost/tokenizer.hpp>
@ -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;

View File

@ -91,6 +91,8 @@ public:
BOOL getInfo(BOOL vram_only, bool disable_wmi);
// </FS:Ansariel>
std::string getDriverVersionWMI();
S32 getVRAM() const { return mVRAM; }
LLSD getDisplayInfo();

View File

@ -399,6 +399,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;
}
@ -1000,7 +1034,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();
}
}
}

View File

@ -4003,10 +4003,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

View File

@ -1243,7 +1243,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);
@ -1254,14 +1254,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)
{

View File

@ -140,6 +140,11 @@ public:
*/
static void toggleBlock(const LLUUID& id);
/**
* Mute/unmute avatar.
*/
static void toggleMute(const LLUUID& id, U32 flags);
/**
* Block/unblock the avatar voice.
*/

View File

@ -40,10 +40,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"
@ -51,7 +55,6 @@
#include "llstylemap.h"
#include "llslurl.h"
#include "lllayoutstack.h"
#include "llagent.h"
#include "llnotificationsutil.h"
#include "lltoastnotifypanel.h"
#include "lltooltip.h"
@ -63,7 +66,6 @@
#include "llurlaction.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llmutelist.h"
// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f)
#include "rlvcommon.h"
// [/RLVa:KB]
@ -200,6 +202,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();
@ -258,11 +415,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());
}
}
@ -278,24 +460,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()
@ -305,6 +532,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));
@ -613,9 +842,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)
{

View File

@ -1151,11 +1151,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)
{
@ -2097,24 +2097,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

View File

@ -178,7 +178,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();

View File

@ -4209,8 +4209,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"));
}

View File

@ -327,6 +327,8 @@ public:
*/
static std::string getSubstitutionName(const LLNotificationPtr& notification);
static std::string getSubstitutionOriginalName(const LLNotificationPtr& notification);
/**
* Adds notification panel to the IM floater.
*/

View File

@ -325,6 +325,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)
{

View File

@ -155,6 +155,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<LLScreenChannel*>(mChannel.get());
if(channel)

View File

@ -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"

View File

@ -89,8 +89,8 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
}
std::string session_name = notification->getPayload()["SESSION_NAME"];
const std::string name = notification->getSubstitutions()["NAME"];
const LLUUID agent_id = notification->getSubstitutions()["AGENT-ID"]; // [FIRE-3522 : SJ]
const std::string name = LLHandlerUtil::getSubstitutionOriginalName(notification);
const LLUUID agent_id = notification->getSubstitutions()["AGENT-ID"]; // [FIRE-3522 : SJ]
if (session_name.empty())
{

View File

@ -1704,13 +1704,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;

View File

@ -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"));
}

View File

@ -1695,6 +1695,10 @@ void remove_inventory_category(
LLPointer<LLViewerInventoryCategory> 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");
@ -1809,6 +1813,10 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> 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);
}

View File

@ -3579,11 +3579,13 @@ 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;
// [RLVa:KB] - Checked: RLVa-1.2.2
// Only anonymize the name if the agent is nearby, there isn't an open IM session to them and their profile isn't open
bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
(RlvActions::canShowName(RlvActions::SNC_DEFAULT, from_id)) || (!RlvUtil::isNearbyAgent(from_id)) || (RlvUIEnabler::hasOpenProfile(from_id)) || (RlvUIEnabler::hasOpenIM(from_id));
args["NAME"] = LLSLURL("agent", from_id, (fRlvCanShowName) ? "completename" : "rlvanonym").getSLURLString();;
args["ORIGINAL_NAME"] = fRlvCanShowName ? original_name : RlvStrings::getAnonym(original_name);
// [/RLVa:KB]
LLSD payload;
payload["from_id"] = from_id;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<menu
<toggleable_menu
height="101"
layout="topleft"
left="100"
@ -142,5 +142,43 @@
name="Mute Text">
<on_click function="AvatarIcon.Action" parameter="mute_unmute" />
<on_check function="AvatarIcon.Check" parameter="is_muted" />
</menu_item_check>
</menu>
</menu_item_check>
<menu_item_separator layout="topleft" name="Moderator Options Separator"/>
<context_menu
label="Moderator Options"
layout="topleft"
name="Moderator Options">
<menu_item_check
label="Allow text chat"
layout="topleft"
name="AllowTextChat">
<on_check function="AvatarIcon.Check" parameter="is_allowed_text_chat" />
<on_click function="AvatarIcon.Action" parameter="toggle_allow_text_chat" />
<on_enable function="AvatarIcon.Enable" parameter="can_allow_text_chat" />
</menu_item_check>
<menu_item_call
label="Mute this participant"
layout="topleft"
name="ModerateVoiceMuteSelected">
<on_click function="AvatarIcon.Action" parameter="group_mute" />
<on_enable function="AvatarIcon.Enable" parameter="can_mute" />
<on_visible function="AvatarIcon.Visible" parameter="show_mute" />
</menu_item_call>
<menu_item_call
label="Unmute this participant"
layout="topleft"
name="ModerateVoiceUnMuteSelected">
<on_click function="AvatarIcon.Action" parameter="group_unmute" />
<on_enable function="AvatarIcon.Enable" parameter="can_unmute" />
<on_visible function="AvatarIcon.Visible" parameter="show_unmute" />
</menu_item_call>
</context_menu>
<menu_item_separator layout="topleft" name="Group Ban Separator"/>
<menu_item_call
label="Ban member"
layout="topleft"
name="BanMember">
<on_click function="AvatarIcon.Action" parameter="ban_member" />
<on_enable function="AvatarIcon.Enable" parameter="can_ban_member" />
</menu_item_call>
</toggleable_menu>

View File

@ -8080,6 +8080,7 @@ Do you want to keep it? "Mute" will block all future offers or messages from [NA
label="Teleport offer from [NAME_LABEL]"
log_to_im="true"
log_to_chat="false"
fade_toast="false"
type="offer"
sound="UISndTeleportOffer">
[NAME_SLURL] has offered to teleport you to their location:
@ -8222,6 +8223,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]
@ -8598,6 +8600,7 @@ Other Key Experiences may be available.
icon="notify.tga"
name="ScriptQuestionExperience"
persist="false"
fade_toast="false"
type="notify">
&apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, an object owned by &apos;[NAME]&apos;, requests your participation in the [GRID_WIDE] experience: