/** * * Copyright (c) 2009-2010, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt * * By copying, modifying or distributing this software, you acknowledge that * you have read and understood your obligations described above, and agree to * abide by those obligations. * */ #include "llviewerprecompiledheaders.h" #include "llavatarnamecache.h" #include "llclipboard.h" #include "llscrolllistctrl.h" #include "llviewerjointattachment.h" #include "llviewerobjectlist.h" #include "llvoavatarself.h" #include "lluictrlfactory.h" #include "rlvfloaterbehaviour.h" #include "rlvhelper.h" #include "rlvhandler.h" #include "rlvlocks.h" // ============================================================================ // Helper functions // // Checked: 2010-03-11 (RLVa-1.1.3b) | Modified: RLVa-1.2.0g std::string rlvGetItemNameFromObjID(const LLUUID& idObj, bool fIncludeAttachPt = true) { const LLViewerObject* pObj = gObjectList.findObject(idObj); const LLViewerObject* pObjRoot = (pObj) ? pObj->getRootEdit() : NULL; const LLViewerInventoryItem* pItem = ((pObjRoot) && (pObjRoot->isAttachment())) ? gInventory.getItem(pObjRoot->getAttachmentItemID()) : NULL; std::string strItemName = (pItem) ? pItem->getName() : idObj.asString(); if ( (!fIncludeAttachPt) || (!pObj) || (!pObj->isAttachment()) || (!isAgentAvatarValid()) ) return strItemName; const LLViewerJointAttachment* pAttachPt = get_if_there(gAgentAvatarp->mAttachmentPoints, RlvAttachPtLookup::getAttachPointIndex(pObjRoot), (LLViewerJointAttachment*)NULL); std::string strAttachPtName = (pAttachPt) ? pAttachPt->getName() : std::string("Unknown"); return llformat("%s (%s%s)", strItemName.c_str(), strAttachPtName.c_str(), (pObj == pObjRoot) ? "" : ", child"); } // Checked: 2011-05-23 (RLVa-1.3.0c) | Added: RLVa-1.3.0c bool rlvGetShowException(ERlvBehaviour eBhvr) { switch (eBhvr) { case RLV_BHVR_RECVCHAT: case RLV_BHVR_RECVEMOTE: case RLV_BHVR_SENDIM: case RLV_BHVR_RECVIM: case RLV_BHVR_STARTIM: case RLV_BHVR_TPLURE: case RLV_BHVR_ACCEPTTP: return true; default: return false; } } // ============================================================================ // RlvFloaterBehaviours member functions // Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e void RlvFloaterBehaviours::onOpen() { m_ConnRlvCommand = gRlvHandler.setCommandCallback(boost::bind(&RlvFloaterBehaviours::onCommand, this, _1, _2)); refreshAll(); } // Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e void RlvFloaterBehaviours::onClose(bool fQuitting) { m_ConnRlvCommand.disconnect(); LLFloater::onClose(fQuitting); } RlvFloaterBehaviours::RlvFloaterBehaviours(const LLSD& key) : LLFloater(std::string("rlvBehaviours")) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_rlv_behaviours.xml"); } void RlvFloaterBehaviours::toggle(void*) { RlvFloaterBehaviours::toggleInstance(); } BOOL RlvFloaterBehaviours::visible(void*) { return RlvFloaterBehaviours::instanceVisible(); } // Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e void RlvFloaterBehaviours::onAvatarNameLookup(const LLUUID& idAgent, const LLAvatarName& avName) { uuid_vec_t::iterator itLookup = std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idAgent); if (itLookup != m_PendingLookup.end()) m_PendingLookup.erase(itLookup); if (getVisible()) refreshAll(); } // Checked: 2011-05-26 (RLVa-1.3.1c) | Added: RLVa-1.3.1c void RlvFloaterBehaviours::onBtnCopyToClipboard() { std::ostringstream strRestrictions; strRestrictions << RlvStrings::getVersion() << "\n"; const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap(); for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj) { strRestrictions << "\n" << rlvGetItemNameFromObjID(itObj->first) << ":\n"; const rlv_command_list_t* pCommands = itObj->second.getCommandList(); for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd) { std::string strOption; LLUUID idOption; if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) && (idOption.notNull()) ) { LLAvatarName avName; if (gObjectList.findObject(idOption)) strOption = rlvGetItemNameFromObjID(idOption, true); else if (LLAvatarNameCache::get(idOption, &avName)) strOption = (!avName.mUsername.empty()) ? avName.mUsername : avName.mDisplayName; else if (!gCacheName->getGroupName(idOption, strOption)) strOption = itCmd->getOption(); } strRestrictions << " -> " << itCmd->asString(); if ( (!strOption.empty()) && (strOption != itCmd->getOption()) ) strRestrictions << " [" << strOption << "]"; if (RLV_RET_SUCCESS != itCmd->getReturnType()) strRestrictions << " (" << RlvStrings::getStringFromReturnCode(itCmd->getReturnType()) << ")"; strRestrictions << "\n"; } } LLWString text = utf8str_to_wstring(strRestrictions.str()); gClipboard.copyFromSubstring(text,0,text.length()); } // Checked: 2011-05-23 (RLVa-1.3.1c) | Modified: RLVa-1.3.1c void RlvFloaterBehaviours::onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet) { if ( (RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType()) ) refreshAll(); } // Checked: 2011-05-23 (RLVa-1.3.1c) | Added: RLVa-1.3.1c BOOL RlvFloaterBehaviours::postBuild() { getChild("copy_btn")->setCommitCallback(boost::bind(&RlvFloaterBehaviours::onBtnCopyToClipboard, this)); return TRUE; } // Checked: 2011-05-23 (RLVa-1.3.1c) | Modified: RLVa-1.3.1c void RlvFloaterBehaviours::refreshAll() { LLCtrlListInterface* pBhvrList = childGetListInterface("behaviour_list"); LLCtrlListInterface* pExceptList = childGetListInterface("exception_list"); if ( (!pBhvrList) || (!pExceptList) ) return; pBhvrList->operateOnAll(LLCtrlListInterface::OP_DELETE); pExceptList->operateOnAll(LLCtrlListInterface::OP_DELETE); if (!isAgentAvatarValid()) return; // // Set-up a row we can just reuse // LLSD sdBhvrRow; LLSD& sdBhvrColumns = sdBhvrRow["columns"]; sdBhvrColumns[0] = LLSD().with("column", "behaviour").with("type", "text"); sdBhvrColumns[1] = LLSD().with("column", "issuer").with("type", "text"); LLSD sdExceptRow; LLSD& sdExceptColumns = sdExceptRow["columns"]; sdExceptColumns[0] = LLSD().with("column", "behaviour").with("type", "text"); sdExceptColumns[1] = LLSD().with("column", "option").with("type", "text"); sdExceptColumns[2] = LLSD().with("column", "issuer").with("type", "text"); // // List behaviours // const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap(); for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj) { const std::string strIssuer = rlvGetItemNameFromObjID(itObj->first); const rlv_command_list_t* pCommands = itObj->second.getCommandList(); for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd) { std::string strOption; LLUUID idOption; if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) && (idOption.notNull()) ) { LLAvatarName avName; if (gObjectList.findObject(idOption)) { strOption = rlvGetItemNameFromObjID(idOption, true); } else if (LLAvatarNameCache::get(idOption, &avName)) { strOption = (!avName.mUsername.empty()) ? avName.mUsername : avName.mDisplayName; } else if (!gCacheName->getGroupName(idOption, strOption)) { if (m_PendingLookup.end() == std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idOption)) { LLAvatarNameCache::get(idOption, boost::bind(&RlvFloaterBehaviours::onAvatarNameLookup, this, _1, _2)); m_PendingLookup.push_back(idOption); } strOption = itCmd->getOption(); } } if ( (itCmd->hasOption()) && (rlvGetShowException(itCmd->getBehaviourType())) ) { // List under the "Exception" tab sdExceptRow["enabled"] = gRlvHandler.isException(itCmd->getBehaviourType(), idOption); sdExceptColumns[0]["value"] = itCmd->getBehaviour(); sdExceptColumns[1]["value"] = strOption; sdExceptColumns[2]["value"] = strIssuer; pExceptList->addElement(sdExceptRow, ADD_BOTTOM); } else { // List under the "Restrictions" tab sdBhvrRow["enabled"] = (RLV_RET_SUCCESS == itCmd->getReturnType()); sdBhvrColumns[0]["value"] = (strOption.empty()) ? itCmd->asString() : itCmd->getBehaviour() + ":" + strOption; sdBhvrColumns[1]["value"] = strIssuer; pBhvrList->addElement(sdBhvrRow, ADD_BOTTOM); } } } } // ============================================================================ // RlvFloaterLocks member functions // // Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a void RlvFloaterLocks::onOpen() { m_ConnRlvCommand = gRlvHandler.setCommandCallback(boost::bind(&RlvFloaterLocks::onRlvCommand, this, _1, _2)); refreshAll(); } // Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a void RlvFloaterLocks::onClose(bool fQuitting) { m_ConnRlvCommand.disconnect(); LLFloater::onClose(fQuitting); } RlvFloaterLocks::RlvFloaterLocks(const LLSD& key) : LLFloater(std::string("rlvLocks")) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_rlv_locks.xml"); } void RlvFloaterLocks::toggle(void*) { RlvFloaterLocks::toggleInstance(); } BOOL RlvFloaterLocks::visible(void*) { return RlvFloaterLocks::instanceVisible(); } // Checked: 2010-03-11 (RLVa-1.2.0a) | Added: RLVa-1.2.0a void RlvFloaterLocks::onRlvCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet) { // Refresh on any successful @XXX=y|n command where XXX is any of the attachment or wearable locking behaviours if ( (RLV_RET_SUCCESS == eRet) && ((RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType())) ) { switch (rlvCmd.getBehaviourType()) { case RLV_BHVR_DETACH: case RLV_BHVR_ADDATTACH: case RLV_BHVR_REMATTACH: case RLV_BHVR_ADDOUTFIT: case RLV_BHVR_REMOUTFIT: refreshAll(); break; default: break; } } } // Checked: 2010-03-18 (RLVa-1.2.0a) | Added: RLVa-1.2.0a void RlvFloaterLocks::refreshAll() { LLCtrlListInterface* pLockList = childGetListInterface("lock_list"); if (!pLockList) return; pLockList->operateOnAll(LLCtrlListInterface::OP_DELETE); if (!isAgentAvatarValid()) return; // // Set-up a row we can just reuse // LLSD sdRow; LLSD& sdColumns = sdRow["columns"]; sdColumns[0]["column"] = "lock_type"; sdColumns[0]["type"] = "text"; sdColumns[1]["column"] = "lock_addrem"; sdColumns[1]["type"] = "text"; sdColumns[2]["column"] = "lock_target"; sdColumns[2]["type"] = "text"; sdColumns[3]["column"] = "lock_origin"; sdColumns[3]["type"] = "text"; // // List attachment locks // sdColumns[0]["value"] = "Attachment"; sdColumns[1]["value"] = "rem"; const RlvAttachmentLocks::rlv_attachobjlock_map_t& attachObjRem = gRlvAttachmentLocks.getAttachObjLocks(); for (RlvAttachmentLocks::rlv_attachobjlock_map_t::const_iterator itAttachObj = attachObjRem.begin(); itAttachObj != attachObjRem.end(); ++itAttachObj) { sdColumns[2]["value"] = rlvGetItemNameFromObjID(itAttachObj->first); sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachObj->second); pLockList->addElement(sdRow, ADD_BOTTOM); } // // List attachment point locks // sdColumns[0]["value"] = "Attachment Point"; sdColumns[1]["value"] = "add"; const RlvAttachmentLocks::rlv_attachptlock_map_t& attachPtAdd = gRlvAttachmentLocks.getAttachPtLocks(RLV_LOCK_ADD); for (RlvAttachmentLocks::rlv_attachptlock_map_t::const_iterator itAttachPt = attachPtAdd.begin(); itAttachPt != attachPtAdd.end(); ++itAttachPt) { const LLViewerJointAttachment* pAttachPt = get_if_there(gAgentAvatarp->mAttachmentPoints, itAttachPt->first, (LLViewerJointAttachment*)NULL); sdColumns[2]["value"] = pAttachPt->getName(); sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachPt->second); pLockList->addElement(sdRow, ADD_BOTTOM); } sdColumns[1]["value"] = "rem"; const RlvAttachmentLocks::rlv_attachptlock_map_t& attachPtRem = gRlvAttachmentLocks.getAttachPtLocks(RLV_LOCK_REMOVE); for (RlvAttachmentLocks::rlv_attachptlock_map_t::const_iterator itAttachPt = attachPtRem.begin(); itAttachPt != attachPtRem.end(); ++itAttachPt) { const LLViewerJointAttachment* pAttachPt = get_if_there(gAgentAvatarp->mAttachmentPoints, itAttachPt->first, (LLViewerJointAttachment*)NULL); sdColumns[2]["value"] = pAttachPt->getName(); sdColumns[3]["value"] = rlvGetItemNameFromObjID(itAttachPt->second); pLockList->addElement(sdRow, ADD_BOTTOM); } // // List wearable type locks // sdColumns[0]["value"] = "Wearable Type"; sdColumns[1]["value"] = "add"; const RlvWearableLocks::rlv_wearabletypelock_map_t& wearableTypeAdd = gRlvWearableLocks.getWearableTypeLocks(RLV_LOCK_ADD); for (RlvWearableLocks::rlv_wearabletypelock_map_t::const_iterator itWearableType = wearableTypeAdd.begin(); itWearableType != wearableTypeAdd.end(); ++itWearableType) { sdColumns[2]["value"] = LLWearableType::getTypeLabel(itWearableType->first); sdColumns[3]["value"] = rlvGetItemNameFromObjID(itWearableType->second); pLockList->addElement(sdRow, ADD_BOTTOM); } sdColumns[1]["value"] = "rem"; const RlvWearableLocks::rlv_wearabletypelock_map_t& wearableTypeRem = gRlvWearableLocks.getWearableTypeLocks(RLV_LOCK_REMOVE); for (RlvWearableLocks::rlv_wearabletypelock_map_t::const_iterator itWearableType = wearableTypeRem.begin(); itWearableType != wearableTypeRem.end(); ++itWearableType) { sdColumns[2]["value"] = LLWearableType::getTypeName(itWearableType->first); sdColumns[3]["value"] = rlvGetItemNameFromObjID(itWearableType->second); pLockList->addElement(sdRow, ADD_BOTTOM); } } // ============================================================================