Ejemplo n.º 1
0
// Checked: 2010-03-18 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
void RlvWearableLocks::removeWearableTypeLock(EWearableType eType, const LLUUID& idRlvObj, ERlvLockMask eLock)
{
/*
	// Sanity check - make sure it's an object we know about
	if ( (m_Objects.find(idRlvObj) == m_Objects.end()) || (!idxAttachPt) )
		return;	// If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE)
*/

	if (eLock & RLV_LOCK_REMOVE)
	{
		RLV_ASSERT( m_WearableTypeRem.lower_bound(eType) != m_WearableTypeRem.upper_bound(eType) ); // The lock should always exist
		for (rlv_wearabletypelock_map_t::iterator itWearableType = m_WearableTypeRem.lower_bound(eType), 
				endWearableType = m_WearableTypeRem.upper_bound(eType); itWearableType != endWearableType; ++itWearableType)
		{
			if (idRlvObj == itWearableType->second)
			{
				m_WearableTypeRem.erase(itWearableType);
				break;
			}
		}
	}
	if (eLock & RLV_LOCK_ADD)
	{
		RLV_ASSERT( m_WearableTypeAdd.lower_bound(eType) != m_WearableTypeAdd.upper_bound(eType) ); // The lock should always exist
		for (rlv_wearabletypelock_map_t::iterator itWearableType = m_WearableTypeAdd.lower_bound(eType), 
				endWearableType = m_WearableTypeAdd.upper_bound(eType); itWearableType != endWearableType; ++itWearableType)
		{
			if (idRlvObj == itWearableType->second)
			{
				m_WearableTypeAdd.erase(itWearableType);
				break;
			}
		}
	}
}
Ejemplo n.º 2
0
// Checked: 2010-03-01 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
void RlvUIEnabler::onToggleUnsit()
{
    bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT);

    LLPanelStandStopFlying* pPanelStand = LLPanelStandStopFlying::getInstance();
    RLV_ASSERT(pPanelStand);
    if (pPanelStand)
    {
        LLButton* pBtnStand = pPanelStand->findChild<LLButton>("stand_btn");
        RLV_ASSERT(pBtnStand);
        if (pBtnStand)
            pBtnStand->setEnabled(fEnable);
    }
}
Ejemplo n.º 3
0
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
void RlvAttachmentLocks::removeAttachmentLock(const LLUUID& idAttachObj, const LLUUID& idRlvObj)
{
/*
	// Sanity check - make sure it's an object we know about
	if ( (m_Objects.find(idRlvObj) == m_Objects.end()) || (!idxAttachPt) )
		return;	// If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE)
*/

#ifndef RLV_RELEASE
	// NOTE: pObj *can* be NULL [see comments for @detach=n in RlvHandler::onAddRemDetach()]
	const LLViewerObject* pDbgObj = gObjectList.findObject(idAttachObj);
	// Assertion: if the object exists then it's an attachment and always specifies the root
	RLV_VERIFY( (!pDbgObj) || ((pDbgObj->isAttachment()) && (pDbgObj == pDbgObj->getRootEdit())) );
#endif // RLV_RELEASE

	// NOTE: try to remove the lock even if pObj isn't an attachment (ie in case the user was able to "Drop" it)
	RLV_ASSERT( m_AttachObjRem.lower_bound(idAttachObj) != m_AttachObjRem.upper_bound(idAttachObj) ); // The lock should always exist
	for (rlv_attachobjlock_map_t::iterator itAttachObj = m_AttachObjRem.lower_bound(idAttachObj), 
			endAttachObj = m_AttachObjRem.upper_bound(idAttachObj); itAttachObj != endAttachObj; ++itAttachObj)
	{
		if (idRlvObj == itAttachObj->second)
		{
			m_AttachObjRem.erase(itAttachObj);
			updateLockedHUD();
			break;
		}
	}
}
Ejemplo n.º 4
0
// Checked: 2010-03-02 (RLVa-1.1.3a) | Modified: RLVa-0.2.0g
std::string RlvInventory::getSharedPath(const LLViewerInventoryCategory* pFolder) const
{
	// Sanity check - no shared root or no folder => no path
	const LLViewerInventoryCategory* pRlvRoot = getSharedRoot();
	if ( (!pRlvRoot) || (!pFolder) || (pRlvRoot->getUUID() == pFolder->getUUID()) )
		return std::string();

	const LLUUID& idRLV  = pRlvRoot->getUUID();
	const LLUUID& idRoot = gInventory.getRootFolderID();
	std::string strPath;

	// Walk up the tree until we reach the top
	RLV_ASSERT(gInventory.isObjectDescendentOf(pFolder->getUUID(), pRlvRoot->getUUID()));
	while (pFolder)
	{
		strPath = "/" + pFolder->getName() + strPath;

		const LLUUID& idParent = pFolder->getParentUUID();
		if (idRLV == idParent)			// Reached the shared root, we're done
			break;
		else if (idRoot == idParent)	// We reached the agent's inventory root (indicative of a logic error elsewhere)
			return std::string();

		pFolder = gInventory.getCategory(idParent);
	}

	return strPath.erase(0, 1);
}
Ejemplo n.º 5
0
// Checked: 2010-07-28 (RLVa-1.1.3a) | Modified: RLVa-1.2.0i
void RlvAttachmentLockWatchdog::onWearAttachment(const LLUUID& idItem, ERlvWearMask eWearAction)
{
	// We only need to keep track of user wears if there's actually anything locked
	RLV_ASSERT(idItem.notNull());
	LLVOAvatar* pAvatar = gAgent.getAvatarObject();
	if ( (idItem.isNull()) || (!pAvatar) || (!gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
		return;

	// If the attachment point this will end up being attached to is:
	//   - unlocked    : nothing should happen (from RLVa's point of view)
	//   - RLV_LOCK_ADD: the new attachment should get detached and the current one(s) reattached (unless it's currently empty)
	//   - RLV_LOCK_REM:
	//       o eWearAction == RLV_WEAR_ADD     : nothing should happen (from RLVa's point of view)
	//       o eWearAction == RLV_WEAR_REPLACE : examine whether the new attachment can indeed replace/detach the old one
	RlvWearInfo infoWear(idItem, eWearAction);
	RLV_ASSERT( (RLV_WEAR_ADD == eWearAction) || (RLV_WEAR_REPLACE == eWearAction) ); // One of the two, but never both
	for (LLVOAvatar::attachment_map_t::const_iterator itAttachPt = pAvatar->mAttachmentPoints.begin(); 
			itAttachPt != pAvatar->mAttachmentPoints.end(); ++itAttachPt)
	{
		const LLViewerJointAttachment* pAttachPt = itAttachPt->second;
		// We only need to know which attachments were present for RLV_LOCK_ADD locked attachment points (and not RLV_LOCK_REM locked ones)
		if (gRlvAttachmentLocks.isLockedAttachmentPoint(pAttachPt, RLV_LOCK_ADD))
		{
			uuid_vec_t attachObjs;
			for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
					itAttachObj != pAttachPt->mAttachedObjects.end(); ++itAttachObj)
			{
				const LLViewerObject* pAttachObj = *itAttachObj;
				if (std::find(m_PendingDetach.begin(), m_PendingDetach.end(), pAttachObj->getAttachmentItemID()) != m_PendingDetach.end())
					continue;	// Exclude attachments that are pending a force-detach
				attachObjs.push_back(pAttachObj->getAttachmentItemID());
			}
			infoWear.attachPts.insert(std::pair<S32, uuid_vec_t>(itAttachPt->first, attachObjs));
		}
	}

	m_PendingWear.insert(std::pair<LLUUID, RlvWearInfo>(idItem, infoWear));
#ifdef RLV_DEBUG
	infoWear.dumpInstance();
#endif // RLV_RELEASE
	startTimer();
}
// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a
F32 RlvWindLightControl::getColorComponent(EColorComponent eComponent, bool& fError) const
{
	switch (eComponent)
	{
		case COMPONENT_R: return getColorVector(fError).mV[0];
		case COMPONENT_G: return getColorVector(fError).mV[1];
		case COMPONENT_B: return getColorVector(fError).mV[2];
		case COMPONENT_I: return get_intensity_from_color(getColorVector(fError));	// SL-2.8: Always seems to be 1.0 so get it manually
		default         : RLV_ASSERT(false); fError = true; return 0.0;
	}
}
Ejemplo n.º 7
0
// Checked: 2010-08-22 (RLVa-1.2.1a) | Added: RLVa-1.2.1a
void RlvUIEnabler::onToggleTp()
{
    // Disable the navigation bar "Home" button if both @tplm=n *and* @tploc=n restricted
    // <FS:Zi> Make navigation bar part of the UI
    // LLButton* pNavBarHomeBtn = LLNavigationBar::getInstance()->findChild<LLButton>("home_btn");
    LLButton* pNavBarHomeBtn = LLNavigationBar::instance().getView()->findChild<LLButton>("home_btn");
    // </FS:Zi>
    RLV_ASSERT(pNavBarHomeBtn);
    if (pNavBarHomeBtn)
        pNavBarHomeBtn->setEnabled(!(gRlvHandler.hasBehaviour(RLV_BHVR_TPLM) && gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)));
}
Ejemplo n.º 8
0
// Checked: 2010-02-28 (RLVa-1.4.0a) | Added: RLVa-1.2.0a
void RlvUIEnabler::onToggleShowMinimap()
{
    bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP);

    // Start or stop filtering showing the mini-map floater
    if (!fEnable)
        addGenericFloaterFilter("mini_map");
    else
        removeGenericFloaterFilter("mini_map");

    // Hide the mini-map floater if it's currently visible (or restore it if it was previously visible)
    static bool fPrevVisibile = false;
    if ( (!fEnable) && ((fPrevVisibile = LLFloaterReg::instanceVisible("mini_map"))) )
        LLFloaterReg::hideInstance("mini_map");
    else if ( (fEnable) && (fPrevVisibile) )
        LLFloaterReg::showInstance("mini_map");

    // Break/reestablish the visibility connection for the nearby people panel embedded minimap instance
    LLPanel* pPeoplePanel = LLFloaterSidePanelContainer::getPanel("people", "panel_people");
    LLPanel* pNetMapPanel = (pPeoplePanel) ? pPeoplePanel->getChild<LLPanel>("minimaplayout", TRUE) : NULL;  //AO: firestorm specific
    RLV_ASSERT( (pPeoplePanel) && (pNetMapPanel) );
    if (pNetMapPanel)
    {
        pNetMapPanel->setMakeVisibleControlVariable( (fEnable) ? gSavedSettings.getControl("ShowRadarMinimap").get() : NULL);
        // Reestablishing the visiblity connection will show the panel if needed so we only need to take care of hiding it when needed
        if ( (!fEnable) && (pNetMapPanel->getVisible()) )
            pNetMapPanel->setVisible(false);
    }

    // Break/reestablish the visibility connection for the radar panel embedded minimap instance
    LLFloater* pRadarFloater = LLFloaterReg::getInstance("fs_radar");
    LLPanel* pRadarNetMapPanel = (pRadarFloater) ? pRadarFloater->getChild<LLPanel>("minimaplayout", TRUE) : NULL;  //AO: firestorm specific
    RLV_ASSERT( (pRadarFloater) && (pRadarNetMapPanel) );
    if (pRadarNetMapPanel)
    {
        pRadarNetMapPanel->setMakeVisibleControlVariable( (fEnable) ? gSavedSettings.getControl("ShowRadarMinimap").get() : NULL);
        // Reestablishing the visiblity connection will show the panel if needed so we only need to take care of hiding it when needed
        if ( (!fEnable) && (pRadarNetMapPanel->getVisible()) )
            pRadarNetMapPanel->setVisible(false);
    }
}
Ejemplo n.º 9
0
// Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h
ERlvBehaviour RlvCommand::getBehaviourFromString(const std::string& strBhvr, bool* pfStrict /*=NULL*/)
{
	std::string::size_type idxStrict = strBhvr.find("_sec");
	bool fStrict = (std::string::npos != idxStrict) && (idxStrict + 4 == strBhvr.length());
	if (pfStrict)
		*pfStrict = fStrict;

	RLV_ASSERT(m_BhvrMap.size() > 0);
	bhvr_map_t::const_iterator itBhvr = m_BhvrMap.find( (!fStrict) ? strBhvr : strBhvr.substr(0, idxStrict));
	if ( (itBhvr != m_BhvrMap.end()) && ((!fStrict) || (hasStrictVariant(itBhvr->second))) )
		return itBhvr->second;
	return RLV_BHVR_UNKNOWN;
}
Ejemplo n.º 10
0
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
void RlvAttachmentLocks::removeAttachmentPointLock(S32 idxAttachPt, const LLUUID& idRlvObj, ERlvLockMask eLock)
{
/*
	// Sanity check - make sure it's an object we know about
	if ( (m_Objects.find(idRlvObj) == m_Objects.end()) || (!idxAttachPt) )
		return;	// If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE)
*/

	if (eLock & RLV_LOCK_REMOVE)
	{
		RLV_ASSERT( m_AttachPtRem.lower_bound(idxAttachPt) != m_AttachPtRem.upper_bound(idxAttachPt) ); // The lock should always exist
		for (rlv_attachptlock_map_t::iterator itAttachPt = m_AttachPtRem.lower_bound(idxAttachPt), 
				endAttachPt = m_AttachPtRem.upper_bound(idxAttachPt); itAttachPt != endAttachPt; ++itAttachPt)
		{
			if (idRlvObj == itAttachPt->second)
			{
				m_AttachPtRem.erase(itAttachPt);
				updateLockedHUD();
				break;
			}
		}
	}
	if (eLock & RLV_LOCK_ADD)
	{
		RLV_ASSERT( m_AttachPtAdd.lower_bound(idxAttachPt) != m_AttachPtAdd.upper_bound(idxAttachPt) ); // The lock should always exist
		for (rlv_attachptlock_map_t::iterator itAttachPt = m_AttachPtAdd.lower_bound(idxAttachPt), 
				endAttachPt = m_AttachPtAdd.upper_bound(idxAttachPt); itAttachPt != endAttachPt; ++itAttachPt)
		{
			if (idRlvObj == itAttachPt->second)
			{
				m_AttachPtAdd.erase(itAttachPt);
				break;
			}
		}
	}
}
Ejemplo n.º 11
0
// Checked: 2010-04-22 (RLVa-1.2.0f) | Modified: RLVa-1.2.0f
bool RlvUtil::isNearbyAgent(const LLUUID& idAgent)
{
	// Sanity check since we call this with notification payloads as well and those strings tend to change from one release to another
	RLV_ASSERT(idAgent.notNull());
	if ( (idAgent.notNull()) && (gAgent.getID() != idAgent) )
	{
		std::vector<LLUUID> idAgents;
		LLWorld::getInstance()->getAvatars(&idAgents, NULL);

		for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++)
			if (idAgents[idxAgent] == idAgent)
				return true;
	}
	return false;
}
Ejemplo n.º 12
0
bool RlvObject::removeCommand(const RlvCommand& rlvCmd)
{
	RLV_ASSERT(RLV_TYPE_REMOVE == rlvCmd.getParamType());

	for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
	{
		//if (*itCmd == rlvCmd) <- commands will never be equal since one is an add and the other is a remove *rolls eyes*
		if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) && 
			 (itCmd->isStrict() == rlvCmd.isStrict() ) )
		{
			m_Commands.erase(itCmd);
			return true;
		}
	}
	return false;	// Command was never added so nothing to remove now
}
Ejemplo n.º 13
0
// Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c
bool RlvCommand::getCommands(bhvr_map_t& cmdList, const std::string &strMatch)
{
	if (strMatch.empty())
		return false;
	cmdList.clear();

	RLV_ASSERT(m_BhvrMap.size() > 0);
	for (bhvr_map_t::const_iterator itBhvr = m_BhvrMap.begin(); itBhvr != m_BhvrMap.end(); ++itBhvr)
	{
		std::string strCmd = itBhvr->first; ERlvBehaviour eBhvr = itBhvr->second;
		if (std::string::npos != strCmd.find(strMatch))
			cmdList.insert(std::pair<std::string, ERlvBehaviour>(strCmd, eBhvr));
		if ( (hasStrictVariant(eBhvr)) && (std::string::npos != strCmd.append("_sec").find(strMatch)) )
			cmdList.insert(std::pair<std::string, ERlvBehaviour>(strCmd, eBhvr));
	}
	return (0 != cmdList.size());
}
Ejemplo n.º 14
0
// Checked: 2010-03-19 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
bool RlvAttachmentLocks::isLockedAttachmentExcept(const LLViewerObject* pObj, const LLUUID& idRlvObj) const
{
	if (idRlvObj.isNull())
		return isLockedAttachment(pObj);

	// If pObj is valid then it should always specify a root since we store root UUIDs in m_AttachObjRem
	RLV_ASSERT( (!pObj) || (pObj == pObj->getRootEdit()) );

	// Loop over every object that has the specified attachment locked (but ignore any locks owned by idRlvObj)
	for (rlv_attachobjlock_map_t::const_iterator itAttachObj = m_AttachObjRem.lower_bound(pObj->getID()), 
			endAttachObj = m_AttachObjRem.upper_bound(pObj->getID()); itAttachObj != endAttachObj; ++itAttachObj)
	{
		if (itAttachObj->second != idRlvObj)
			return true;
	}
	return isLockedAttachmentPointExcept(RlvAttachPtLookup::getAttachPointIndex(pObj), RLV_LOCK_REMOVE, idRlvObj);
}
Ejemplo n.º 15
0
// Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem)
{
	if ( (pItem) && (RlvForceWear::isWearableItem(pItem)) )
	{
		switch (pItem->getType())
		{
			case LLAssetType::AT_BODYPART:
			case LLAssetType::AT_CLOTHING:
				return gRlvWearableLocks.canRemove(pItem);
			case LLAssetType::AT_OBJECT:
				return gRlvAttachmentLocks.canDetach(pItem);
			case LLAssetType::AT_GESTURE:
				return true;
			default:
				RLV_ASSERT(false);
		}
	}
	return false;
}
Ejemplo n.º 16
0
bool RlvObject::addCommand(const RlvCommand& rlvCmd)
{
	RLV_ASSERT(RLV_TYPE_ADD == rlvCmd.getParamType());

	// Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on)
	for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
	{
		if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) && 
			 (itCmd->isStrict() == rlvCmd.isStrict() ) )
		{
			return false;
		}
	}

	// Now that we know it's not a duplicate, add it to the end of the list
	m_Commands.push_back(rlvCmd);

	return true;
}
void LLFloaterAvatarPicker::onList()
{
	getChildView("ok_btn")->setEnabled(isSelectBtnEnabled());

// [RLVa:KB] - Checked: 2010-06-05 (RLVa-1.2.2a) | Modified: RLVa-1.2.0d
	if (rlv_handler_t::isEnabled())
	{
		LLTabContainer* pTabs = getChild<LLTabContainer>("ResidentChooserTabs");
		LLPanel* pNearMePanel = getChild<LLPanel>("NearMePanel");
		RLV_ASSERT( (pTabs) && (pNearMePanel) );
		if ( (pTabs) && (pNearMePanel) )
		{
			bool fRlvEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES);
			pTabs->enableTabButton(pTabs->getIndexForPanel(pNearMePanel), fRlvEnable);
			if ( (!fRlvEnable) && (pTabs->getCurrentPanel() == pNearMePanel) )
				pTabs->selectTabByName("SearchPanel");
		}
	}
// [/RLVa:KB]
}
Ejemplo n.º 18
0
// Checked: 2010-07-28 (RLVa-1.1.3a) | Modified: RLVa-1.2.0i
void RlvAttachmentLockWatchdog::onDetach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt)
{
	S32 idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(pAttachPt);
	const LLUUID& idAttachItem = (pAttachObj) ? pAttachObj->getAttachmentItemID() : LLUUID::null;
	RLV_ASSERT( (!gAgent.getAvatarObject()) || ((idxAttachPt) && (idAttachItem.notNull())) );
	if ( (!idxAttachPt) || (idAttachItem.isNull()) )
		return;

	// If it's an attachment that's pending force-detach then we don't want to do anything (even if it's currently "remove locked")
	rlv_detach_map_t::iterator itDetach = std::find(m_PendingDetach.begin(), m_PendingDetach.end(), idAttachItem);
	if (itDetach != m_PendingDetach.end())
	{
		m_PendingDetach.erase(itDetach);
		return;
	}

	// If the attachment is currently "remove locked" then we should reattach it (unless it's already pending reattach)
	if (gRlvAttachmentLocks.isLockedAttachment(pAttachObj))
	{
		bool fPendingAttach = false;
		for (rlv_attach_map_t::const_iterator itReattach = m_PendingAttach.lower_bound(idxAttachPt), 
				itReattachEnd = m_PendingAttach.upper_bound(idxAttachPt); itReattach != itReattachEnd; ++itReattach)
		{
			if (itReattach->second.idItem == idAttachItem)
			{
				fPendingAttach = true;
				break;
			}
		}

		// TODO-RLVa: [RLVa-1.2.1] we should re-add the item to COF as well to make sure it'll reattach when the user relogs
		//		-> check the call order in LLVOAvatarSelf::detachObject() since COF removal happens *after* we're called
		if (!fPendingAttach)
		{
			m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(idAttachItem)));
			startTimer();
		}
	}
}
Ejemplo n.º 19
0
// Checked: 2010-12-08 (RLVa-1.4.0a) | Modified: RLVa-1.2.2c
void RlvUIEnabler::onToggleShowNames(bool fQuitting)
{
    if (fQuitting)
        return;							// Nothing to do if the viewer is shutting down

    bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES);

    // Refresh the nearby people list
    // <FS:Ansariel> [Standalone radar]
    //LLPanelPeople* pPeoplePanel = LLFloaterSidePanelContainer::getPanel<LLPanelPeople>("people", "panel_people");
    //RLV_ASSERT( (pPeoplePanel) && (pPeoplePanel->getNearbyList()) );
    //if ( (pPeoplePanel) && (pPeoplePanel->getNearbyList()) )
    //	pPeoplePanel->getNearbyList()->updateAvatarNames();
    FSRadar* pRadar = FSRadar::getInstance();
    RLV_ASSERT( (pRadar) );
    if ( (pRadar) )
        pRadar->updateNames();
    // </FS:Ansariel> [Standalone radar]

    // Refresh the speaker list
    // <FS:Ansariel> [FS communication UI]
    FSFloaterVoiceControls* pCallFloater = LLFloaterReg::findTypedInstance<FSFloaterVoiceControls>("fs_voice_controls");
    if (pCallFloater)
        pCallFloater->getAvatarCallerList()->updateAvatarNames();
    // </FS:Ansariel> [FS communication UI]

    // Force the use of the "display name" cache so we can filter both display and legacy names (or return back to the user's preference)
    if (!fEnable)
    {
        LLAvatarNameCache::setForceDisplayNames(true);
    }
    else
    {
        LLAvatarNameCache::setForceDisplayNames(false);
        LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
    }
    LLVOAvatar::invalidateNameTags();	// See handleDisplayNamesOptionChanged()
}
Ejemplo n.º 20
0
// Checked: 2009-11-25 (RLVa-1.1.0f) | Added: RLVa-1.1.0f
const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet)
{
	// TODO-RLVa: [2009-11-25] clean this up along with the calling code in process_chat_from_simulator() once we're happy with the output
	switch (eRet)
	{
		case RLV_RET_SUCCESS_UNSET:
			return "unset";
		case RLV_RET_SUCCESS_DUPLICATE:
			return "duplicate";
		case RLV_RET_SUCCESS_DELAYED:
			return "delayed";
		case RLV_RET_FAILED_SYNTAX:
			return "thingy error";
		case RLV_RET_FAILED_OPTION:
			return "invalid option";
		case RLV_RET_FAILED_PARAM:
			return "invalid param";
		case RLV_RET_FAILED_LOCK:
			return "locked command";
		case RLV_RET_FAILED_DISABLED:
			return "disabled command";
		case RLV_RET_FAILED_UNKNOWN:
			return "unknown command";
		case RLV_RET_FAILED_NOSHAREDROOT:
			return "missing #RLV";
		// The following are identified by the chat verb
		case RLV_RET_RETAINED:
		case RLV_RET_SUCCESS:
		case RLV_RET_FAILED:
			break;
		// The following shouldn't occur
		case RLV_RET_UNKNOWN:
		default:
			RLV_ASSERT(false);
			break;
	};
	return NULL;
}
Ejemplo n.º 21
0
// Checked: 2010-11-11 (RLVa-1.2.1g) | Modified: RLVa-1.2.1g
bool rlvPredCanWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask)
{
	if ( (pItem) && (RlvForceWear::isWearableItem(pItem)) )
	{
		if (RlvForceWear::isWearingItem(pItem))
			return true; // Special exception for currently worn items
		switch (pItem->getType())
		{
			case LLAssetType::AT_BODYPART:
				// NOTE: only one body part of each type is allowed so the only way to wear one is if we can replace the current one
				return (RLV_WEAR_LOCKED != (gRlvWearableLocks.canWear(pItem) & RLV_WEAR_REPLACE & eWearMask));
			case LLAssetType::AT_CLOTHING:
				return (RLV_WEAR_LOCKED != (gRlvWearableLocks.canWear(pItem) & eWearMask));
			case LLAssetType::AT_OBJECT:
				return (RLV_WEAR_LOCKED != (gRlvAttachmentLocks.canAttach(pItem) & eWearMask));
			case LLAssetType::AT_GESTURE:
				return true;
			default:
				RLV_ASSERT(false);
		}
	}
	return false;
}
Ejemplo n.º 22
0
// Checked: 2015-05-05 (RLVa-1.4.12)
void RlvForceWear::done()
{
	// Sanity check - don't go through all the motions below only to find out there's nothing to actually do
	if ( (m_remWearables.empty()) && (m_remAttachments.empty()) && (m_remGestures.empty()) &&
		 (m_addWearables.empty()) && (m_addAttachments.empty()) && (m_addGestures.empty()) )
	{
		return;
	}

	//
	// Process removals
	//

	uuid_vec_t remItems;

	// Wearables
	if (m_remWearables.size())
	{
		for (const LLViewerWearable* pWearable : m_remWearables)
			remItems.push_back(pWearable->getItemID());
		m_remWearables.clear();
	}

	// Gestures
	if (m_remGestures.size())
	{
		// NOTE: LLGestureMgr::deactivateGesture() will call LLAppearanceMgr::removeCOFItemLinks() for us and supply its own callback
		for (const LLViewerInventoryItem* pItem : m_remGestures)
			LLGestureMgr::instance().deactivateGesture(pItem->getUUID());
		m_remGestures.clear();
	}

	// Attachments
	if (m_remAttachments.size())
	{
		LLAgentWearables::userRemoveMultipleAttachments(m_remAttachments);
		for (const LLViewerObject* pAttachObj : m_remAttachments)
			remItems.push_back(pAttachObj->getAttachmentItemID());
		m_remAttachments.clear();
	}

	//
	// Process additions
	//

	// Wearables need to be split into AT_BODYPART and AT_CLOTHING for COF
	LLInventoryModel::item_array_t addBodyParts, addClothing;
	for (addwearables_map_t::const_iterator itAddWearables = m_addWearables.cbegin(); itAddWearables != m_addWearables.cend(); ++itAddWearables)
	{
		// NOTE: LLAppearanceMgr will filter our duplicates so no need for us to check here
		for (LLViewerInventoryItem* pItem : itAddWearables->second)
		{
			if (LLAssetType::AT_BODYPART == pItem->getType())
				addBodyParts.push_back(pItem);
			else
				addClothing.push_back(pItem);
		}
	}
	m_addWearables.clear();

	// Until LL provides a way for updateCOF to selectively attach add/replace we have to deal with attachments ourselves
	for (addattachments_map_t::const_iterator itAddAttachments = m_addAttachments.cbegin(); itAddAttachments != m_addAttachments.cend(); ++itAddAttachments)
	{
		for (const LLViewerInventoryItem* pItem : itAddAttachments->second)
			addPendingAttachment(pItem->getLinkedUUID(), itAddAttachments->first);
	}
	m_addAttachments.clear();

	//
	// Tie it all together
	//

	//          |    Wearables    |   Attachments    |   Gestures      |
	//          |======================================================|
	// Add    : | LLAppearanceMgr | <custom>         | LLAppearanceMgr |
	// Remove : | LLAppearanceMgr | LLAppearanceMgr  | LLGestureMgr    |
	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy(false, false, boost::bind(RlvForceWear::updatePendingAttachments));

	if (!remItems.empty())
	{
		LLAppearanceMgr::instance().removeItemsFromAvatar(remItems, cb, true);
	}

	if ( (addBodyParts.empty()) && (!addClothing.empty()) && (m_addGestures.empty()) )
	{
		// Clothing items only
		uuid_vec_t idClothing;
		for (const LLViewerInventoryItem* pItem : addClothing)
			idClothing.push_back(pItem->getUUID());
		LLAppearanceMgr::instance().wearItemsOnAvatar(idClothing, false, false, cb);
	}
	else if ( (!addBodyParts.empty()) || (!addClothing.empty()) || (!m_addGestures.empty()) )
	{
		// Mixture of body parts, clothing and/or gestures
		LLInventoryModel::item_array_t addAttachments;
		LLAppearanceMgr::instance().updateCOF(addBodyParts, addClothing, addAttachments, m_addGestures, true, LLUUID::null, cb);

		m_addGestures.clear();
	}

	// Make sure there are no leftovers for the next cycle
	RLV_ASSERT( (m_remWearables.empty()) && (m_remAttachments.empty()) && (m_remGestures.empty()) );
	RLV_ASSERT( (m_addWearables.empty()) && (m_addAttachments.empty()) && (m_addGestures.empty()) );
}
Ejemplo n.º 23
0
// Checked: 2010-09-18 (RLVa-1.2.1)
void RlvForceWear::done()
{
	// Sanity check - don't go through all the motions below only to find out there's nothing to actually do
	if ( (m_remWearables.empty()) && (m_remAttachments.empty()) && (m_remGestures.empty()) &&
		 (m_addWearables.empty()) && (m_addAttachments.empty()) && (m_addGestures.empty()) )
	{
		return;
	}

	LLAppearanceMgr* pAppearanceMgr = LLAppearanceMgr::getInstance();
	
	//
	// Process removals
	//

	// Wearables
	if (m_remWearables.size())
	{
		for (std::list<const LLViewerWearable*>::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable)
			pAppearanceMgr->removeItemFromAvatar((*itWearable)->getItemID());
		m_remWearables.clear();
	}

	// Gestures
	if (m_remGestures.size())
	{
		// NOTE: LLGestureMgr::deactivateGesture() will call LLAppearanceMgr::removeCOFItemLinks() for us
		for (S32 idxItem = 0, cntItem = m_remGestures.count(); idxItem < cntItem; idxItem++)
			LLGestureMgr::instance().deactivateGesture(m_remGestures.get(idxItem)->getUUID());
		m_remGestures.clear();
	}

	// Attachments
	if (m_remAttachments.size())
	{
		// Don't bother with COF if all we're doing is detaching some attachments (keeps people from rebaking on every @remattach=force)
		LLAgentWearables::userRemoveMultipleAttachments(m_remAttachments);

		for (std::vector<LLViewerObject*>::const_iterator itAttachObj = m_remAttachments.begin(); 
				itAttachObj != m_remAttachments.end(); ++itAttachObj)
		{
			pAppearanceMgr->removeCOFItemLinks((*itAttachObj)->getAttachmentItemID());
		}

		m_remAttachments.clear();
	}

	//
	// Process additions
	//

	// Wearables need to be split into AT_BODYPART and AT_CLOTHING for COF
	LLInventoryModel::item_array_t addBodyParts, addClothing;
	for (addwearables_map_t::const_iterator itAddWearables = m_addWearables.begin(); itAddWearables != m_addWearables.end(); ++itAddWearables)
	{
		const LLInventoryModel::item_array_t& wearItems = itAddWearables->second;
		for (S32 idxItem = 0, cntItem = wearItems.count(); idxItem < cntItem; idxItem++)
		{
			LLViewerInventoryItem* pItem = wearItems.get(idxItem);
			if (!pAppearanceMgr->isLinkInCOF(pItem->getUUID()))		// It's important to examine COF here and *not* gAgentWearables
			{
				if (LLAssetType::AT_BODYPART == pItem->getType())
					addBodyParts.push_back(pItem);
				else
					addClothing.push_back(pItem);
			}
		}
	}
	m_addWearables.clear();

	// Until LL provides a way for updateCOF to selectively attach add/replace we have to deal with attachments ourselves
	for (addattachments_map_t::const_iterator itAddAttachments = m_addAttachments.begin(); 
			itAddAttachments != m_addAttachments.end(); ++itAddAttachments)
	{
		const LLInventoryModel::item_array_t& wearItems = itAddAttachments->second;
		for (S32 idxItem = 0, cntItem = wearItems.count(); idxItem < cntItem; idxItem++)
		{
			const LLUUID& idItem = wearItems.get(idxItem)->getLinkedUUID();
			if (gAgentAvatarp->attachmentWasRequested(idItem))
				continue;
			gAgentAvatarp->addAttachmentRequest(idItem);

			LLAttachmentsMgr::instance().addAttachment(idItem, itAddAttachments->first & ~ATTACHMENT_ADD, itAddAttachments->first & ATTACHMENT_ADD);
		}
	}
	m_addAttachments.clear();

	// If there are additions we need to call LLAppearanceManager::updateCOF(), otherwise LLAppearanceManager::updateAppearanceFromCOF()
	if ( (!addBodyParts.empty()) || (!addClothing.empty()) || (!m_addGestures.empty()) )
	{
		LLInventoryModel::item_array_t addAttachments;
		pAppearanceMgr->updateCOF(addBodyParts, addClothing, addAttachments, m_addGestures, true);

		m_addGestures.clear();
	}

	// Since RlvForceWear is a singleton now we want to be sure there aren't any leftovers
	RLV_ASSERT( (m_remWearables.empty()) && (m_remAttachments.empty()) && (m_remGestures.empty()) );
	RLV_ASSERT( (m_addWearables.empty()) && (m_addAttachments.empty()) && (m_addGestures.empty()) );
}
Ejemplo n.º 24
0
// Checked: 2010-03-21 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAction eAction, EWearFlags eFlags)
{
	// [See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items]
	if (!gAgentWearables.areWearablesLoaded())
	{
		LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
		return;
	}
	if (!isAgentAvatarValid())
		return;

	// Grab a list of all the items we'll be wearing/attaching
	LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
	RlvWearableItemCollector f(pFolder, eAction, eFlags);
	gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, f, TRUE);

	// TRUE if we've already encountered this LLWearableType::EType (used only on wear actions and only for AT_CLOTHING)
	bool fSeenWType[LLWearableType::WT_COUNT] = { false };

	EWearAction eCurAction = eAction;
	for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
	{
		LLViewerInventoryItem* pRlvItem = items.get(idxItem);
		LLViewerInventoryItem* pItem = (LLAssetType::AT_LINK == pRlvItem->getActualType()) ? pRlvItem->getLinkedItem() : pRlvItem;

		// If it's wearable it should be worn on detach
//		if ( (ACTION_DETACH == eAction) && (isWearableItem(pItem)) && (!isWearingItem(pItem)) )
//			continue;

		// Each folder can specify its own EWearAction override
		if (isWearAction(eAction))
			eCurAction = f.getWearAction(pRlvItem->getParentUUID());
		else
			eCurAction = eAction;

		//  NOTES: * if there are composite items then RlvWearableItemCollector made sure they can be worn (or taken off depending)
		//         * some scripts issue @remattach=force,attach:worn-items=force so we need to attach items even if they're currently worn
		switch (pItem->getType())
		{
			case LLAssetType::AT_BODYPART:
				RLV_ASSERT(isWearAction(eAction));	// RlvWearableItemCollector shouldn't be supplying us with body parts on detach
			case LLAssetType::AT_CLOTHING:
				if (isWearAction(eAction))
				{
					// The first time we encounter any given clothing type we use 'eCurAction' (replace or add)
					// The second time we encounter a given clothing type we'll always add (rather than replace the previous iteration)
					eCurAction = (!fSeenWType[pItem->getWearableType()]) ? eCurAction : ACTION_WEAR_ADD;

					ERlvWearMask eWearMask = gRlvWearableLocks.canWear(pRlvItem);
					if ( ((ACTION_WEAR_REPLACE == eCurAction) && (eWearMask & RLV_WEAR_REPLACE)) ||
						 ((ACTION_WEAR_ADD == eCurAction) && (eWearMask & RLV_WEAR_ADD)) )
					{
						// The check for whether we're replacing a currently worn composite item happens in onWearableArrived()
						if (!isAddWearable(pItem))
							addWearable(pRlvItem, eCurAction);
						fSeenWType[pItem->getWearableType()] = true;
					}
				}
				else
				{
					const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(pItem->getUUID());
					if ( (pWearable) && (isForceRemovable(pWearable, false)) )
						remWearable(pWearable);
				}
				break;

			case LLAssetType::AT_OBJECT:
				if (isWearAction(eAction))
				{
					ERlvWearMask eWearMask = gRlvAttachmentLocks.canAttach(pRlvItem);
					if ( ((ACTION_WEAR_REPLACE == eCurAction) && (eWearMask & RLV_WEAR_REPLACE)) ||
						 ((ACTION_WEAR_ADD == eCurAction) && (eWearMask & RLV_WEAR_ADD)) )
					{
						if (!isAddAttachment(pRlvItem))
						{
							#ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
							// We still need to check whether we're about to replace a currently worn composite item
							// (which we're not if we're just reattaching an attachment we're already wearing)
							LLViewerInventoryCategory* pCompositeFolder = NULL;
							if ( (pAttachPt->getObject()) && (RlvSettings::getEnableComposites()) && 
								 (pAttachPt->getItemID() != pItem->getUUID()) &&
								 (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pCompositeFolder)) )
							{
								// If we can't take off the composite folder this item would replace then don't allow it to get attached
								if (gRlvHandler.canTakeOffComposite(pCompositeFolder))
								{
									forceFolder(pCompositeFolder, ACTION_DETACH, FLAG_DEFAULT);
									addAttachment(pRlvItem);
								}
							}
							else
							#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
							{
								addAttachment(pRlvItem, eCurAction);
							}
						}
					}
				}
				else
				{
					const LLViewerObject* pAttachObj = gAgentAvatarp->getWornAttachment(pItem->getUUID());
					if ( (pAttachObj) && (isForceDetachable(pAttachObj, false)) )
						remAttachment(pAttachObj);
				}
				break;

			#ifdef RLV_EXTENSION_FORCEWEAR_GESTURES
			case LLAssetType::AT_GESTURE:
				if (isWearAction(eAction))
				{
					if (std::find_if(m_addGestures.begin(), m_addGestures.end(), RlvPredIsEqualOrLinkedItem(pRlvItem)) == m_addGestures.end())
						m_addGestures.push_back(pRlvItem);
				}
				else
				{
					if (std::find_if(m_remGestures.begin(), m_remGestures.end(), RlvPredIsEqualOrLinkedItem(pRlvItem)) == m_remGestures.end())
						m_remGestures.push_back(pRlvItem);
				}
				break;
			#endif // RLV_EXTENSION_FORCEWEAR_GESTURES

			default:
				break;
		}
	}
}
Ejemplo n.º 25
0
// Checked: 2010-09-23 (RLVa-1.1.3a) | Modified: RLVa-1.2.1d
void RlvAttachmentLockWatchdog::onAttach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt)
{
	S32 idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(pAttachObj);
	const LLUUID& idAttachItem = (pAttachObj) ? pAttachObj->getAttachmentItemID() : LLUUID::null;
	RLV_ASSERT( (!gAgent.getAvatarObject()) || ((idxAttachPt) && (idAttachItem.notNull())) );
	if ( (!idxAttachPt) || (idAttachItem.isNull()) )
		return;

	// Check if the attachment point has a pending "reattach"
	rlv_attach_map_t::iterator itAttach = m_PendingAttach.lower_bound(idxAttachPt), itAttachEnd = m_PendingAttach.upper_bound(idxAttachPt);
	if (itAttach != itAttachEnd)
	{
		bool fPendingReattach = false;
		for (; itAttach != itAttachEnd; ++itAttach)
		{
			if (idAttachItem == itAttach->second.idItem)
			{
				fPendingReattach = true;
				m_PendingAttach.erase(itAttach);
				break;
			}
		}
		if (!fPendingReattach)
			detach(pAttachObj);
		return;
	}

	// Check if the attach was allowed at the time it was requested
	rlv_wear_map_t::iterator itWear = m_PendingWear.find(idAttachItem);
	if (itWear != m_PendingWear.end())
	{
		// We'll need to return the attachment point to its previous state if it was non-attachable
		if (itWear->second.isAddLockedAttachPt(idxAttachPt))
		{
			// Get the saved state of the attachment point (but do nothing if the item itself was already worn then)
			std::map<S32, uuid_vec_t>::iterator itAttachPrev = itWear->second.attachPts.find(idxAttachPt);
			RLV_ASSERT(itAttachPrev != itWear->second.attachPts.end());
			if (std::find(itAttachPrev->second.begin(), itAttachPrev->second.end(), idAttachItem) == itAttachPrev->second.end())
			{
				// If it was empty we need to detach everything on the attachment point; if it wasn't we need to restore it to what it was
				if (itAttachPrev->second.empty())
				{
					detach(idxAttachPt);
				}
				else
				{
					// Iterate over all the current attachments and force detach any that shouldn't be there
					c_llvo_vec_t attachObjs;
					for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
							itAttachObj != pAttachPt->mAttachedObjects.end(); ++itAttachObj)
					{
						const LLViewerObject* pAttachObj = *itAttachObj;

						uuid_vec_t::iterator itAttach = 
							std::find(itAttachPrev->second.begin(), itAttachPrev->second.end(), pAttachObj->getAttachmentItemID());
						if (itAttach == itAttachPrev->second.end())
							detach(pAttachObj);
						else
							itAttachPrev->second.erase(itAttach);
					}

					// Whatever is left is something that needs to be reattached
					for (uuid_vec_t::const_iterator itAttach = itAttachPrev->second.begin(); 
							itAttach != itAttachPrev->second.end(); ++itAttach)
					{
						m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(*itAttach)));
					}
				}
			}
		}
		else if (RLV_WEAR_REPLACE == itWear->second.eWearAction)
		{
			// Now that we know where this attaches to check if we can actually perform a "replace"
			bool fCanReplace = true;
			for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
					((itAttachObj != pAttachPt->mAttachedObjects.end()) && (fCanReplace)); ++itAttachObj)
			{
				if (pAttachObj != *itAttachObj)
					fCanReplace &= !gRlvAttachmentLocks.isLockedAttachment(*itAttachObj);
			}

			if (fCanReplace)
				detach(idxAttachPt, pAttachObj);	// Replace == allowed: detach everything except the new attachment
			else
				detach(pAttachObj);					// Replace != allowed: detach the new attachment
		}
		m_PendingWear.erase(itWear); // No need to start the timer since it should be running already if '!m_PendingWear.empty()'
	}
}
// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a
bool RlvWindLight::setValue(const std::string& strRlvName, const std::string& strValue)
{
	F32 nValue = 0.0f;
	// Sanity check - make sure strValue specifies a number for all settings except "preset" and "daycycle"
	if ( (RlvSettings::getNoSetEnv()) || 
		 ( (!LLStringUtil::convertToF32(strValue, nValue)) && (("preset" != strRlvName) && ("daycycle" != strRlvName)) ) )
 	{
		return false;
	}

	LLWLParamManager* pWLParams = LLWLParamManager::getInstance(); 
	LLEnvManagerNew* pEnvMgr = LLEnvManagerNew::getInstance();

	if ("daytime" == strRlvName)
	{
		if (0.0f <= nValue)
		{
			pWLParams->mAnimator.deactivate();
			pWLParams->mAnimator.setDayTime(nValue);
			pWLParams->mAnimator.update(pWLParams->mCurParams);
		}
		else
		{
			pEnvMgr->useRegionSettings();
		}
		return true;
	}
	else if ("preset" == strRlvName)
	{
		std::string strPresetName = pWLParams->findPreset(strValue, LLEnvKey::SCOPE_LOCAL);
		if (!strPresetName.empty())
			pEnvMgr->useSkyPreset(strPresetName);
		return !strPresetName.empty();
	}
	else if ("daycycle" == strRlvName)
	{
		std::string strPresetName = LLDayCycleManager::instance().findPreset(strValue);
		if (!strPresetName.empty())
			pEnvMgr->useDayCycle(strValue, LLEnvKey::SCOPE_LOCAL);
		return !strPresetName.empty();
	}

	bool fError = false;
	pWLParams->mAnimator.deactivate();
	if (("sunglowfocus" == strRlvName) || ("sunglowsize" == strRlvName))
	{
		pWLParams->mGlow = pWLParams->mCurParams.getVector(pWLParams->mGlow.mName, fError);
		RLV_ASSERT_DBG(!fError);

		if ("sunglowfocus" == strRlvName)
			pWLParams->mGlow.b = -nValue * 5;
		else
			pWLParams->mGlow.r = (2 - nValue) * 20;

		pWLParams->mGlow.update(pWLParams->mCurParams);
		pWLParams->propagateParameters();
		return true;
	}
	else if ("starbrightness" == strRlvName)
	{
		pWLParams->mCurParams.setStarBrightness(nValue);
		return true;
	}
	else if (("eastangle" == strRlvName) || ("sunmoonposition" == strRlvName))
	{
		if ("eastangle" == strRlvName)
			pWLParams->mCurParams.setEastAngle(F_TWO_PI * nValue);
		else
			pWLParams->mCurParams.setSunAngle(F_TWO_PI * nValue);

		// Set the sun vector
		pWLParams->mLightnorm.r = -sin(pWLParams->mCurParams.getEastAngle()) * cos(pWLParams->mCurParams.getSunAngle());
		pWLParams->mLightnorm.g = sin(pWLParams->mCurParams.getSunAngle());
		pWLParams->mLightnorm.b = cos(pWLParams->mCurParams.getEastAngle()) * cos(pWLParams->mCurParams.getSunAngle());
		pWLParams->mLightnorm.i = 1.f;

		pWLParams->propagateParameters();
		return true;
	}
	else if ("cloudscrollx" == strRlvName)
	{
		pWLParams->mCurParams.setCloudScrollX(nValue + 10.0f);
		return true;
	}
	else if ("cloudscrolly" == strRlvName)
	{
		pWLParams->mCurParams.setCloudScrollY(nValue + 10.0f);
		return true;
	}

	std::map<std::string, RlvWindLightControl>::iterator itControl = m_ControlLookupMap.find(strRlvName);
	if (m_ControlLookupMap.end() != itControl)
	{
		switch (itControl->second.getControlType())
		{
			case RlvWindLightControl::TYPE_FLOAT:
				return itControl->second.setFloat(nValue);
			case RlvWindLightControl::TYPE_COLOR_R:
				return itControl->second.setColorComponent(RlvWindLightControl::COMPONENT_R, nValue);
			default:
				RLV_ASSERT(false);
		}
	}
	else
	{
		// Couldn't find the exact name, check for a color control name
		RlvWindLightControl::EColorComponent eComponent = RlvWindLightControl::getComponentFromCharacter(strRlvName[strRlvName.length() - 1]);
		if (RlvWindLightControl::COMPONENT_NONE != eComponent)
			itControl = m_ControlLookupMap.find(strRlvName.substr(0, strRlvName.length() - 1));
		if ( (m_ControlLookupMap.end() != itControl) && (itControl->second.isColorType()) )
			return itControl->second.setColorComponent(eComponent, nValue);
	}
	return false;
}
Ejemplo n.º 27
0
// Checked: 2010-03-14 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvRenameOnWearObserver::doneIdle()
{
	const LLViewerInventoryCategory* pRlvRoot = NULL;
	if ( (RlvSettings::getEnableSharedWear()) || (!RlvSettings::getSharedInvAutoRename()) || (LLStartUp::getStartupState() < STATE_STARTED) || 
		 (!isAgentAvatarValid()) || ((pRlvRoot = RlvInventory::instance().getSharedRoot()) == NULL) )
	{
		delete this;
		return;
	}

	const LLViewerJointAttachment* pAttachPt = NULL; S32 idxAttachPt = 0;
	// Kitty says this check really doesn't do much of anything. -- TS
	// RLV_ASSERT(mComplete.size() > 0);	// Catch instances where we forgot to call startFetch()
	for (uuid_vec_t::const_iterator itItem = mComplete.begin(); itItem != mComplete.end(); ++itItem)
	{
		const LLUUID& idAttachItem = *itItem;

		// If the item resides under #RLV we'll rename it directly; otherwise settle for "renaming" all of its links residing under #RLV
		LLInventoryModel::item_array_t items;
		if (gInventory.isObjectDescendentOf(idAttachItem, pRlvRoot->getUUID()))
			items.push_back(gInventory.getItem(idAttachItem));
		else
			items = gInventory.collectLinkedItems(idAttachItem, pRlvRoot->getUUID());
		if (items.empty())
			continue;

		if ( ((pAttachPt = gAgentAvatarp->getWornAttachmentPoint(idAttachItem)) == NULL) ||
			 ((idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(pAttachPt)) == 0) )
		{
			RLV_ASSERT(false);
			continue;
		}

		for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
		{
			LLViewerInventoryItem* pItem = items.get(idxItem);
			if (!pItem)
				continue;

			S32 idxAttachPtItem = RlvAttachPtLookup::getAttachPointIndex(pItem);
			if ( (idxAttachPt == idxAttachPtItem) || (idxAttachPtItem) )
				continue;

			std::string strAttachPt = pAttachPt->getName();
			LLStringUtil::toLower(strAttachPt);

			// If we can modify the item then we rename it directly, otherwise we create a new folder and move it
			if (pItem->getPermissions().allowModifyBy(gAgent.getID()))
			{
				std::string strName = pItem->getName();
				LLStringUtil::truncate(strName, DB_INV_ITEM_NAME_STR_LEN - strAttachPt.length() - 3);

				strName += " (" + strAttachPt + ")";

				pItem->rename(strName);
				pItem->updateServer(FALSE);
				gInventory.addChangedMask(LLInventoryObserver::LABEL, pItem->getUUID());
			}
			else
			{
				// Don't do anything if the item is a direct descendant of the shared root, or a folded folder
				LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
				if ( (pFolder) && (pFolder->getUUID() != pRlvRoot->getUUID()) && (!RlvInventory::isFoldedFolder(pFolder, false)) )
				{
					std::string strFolderName = ".(" + strAttachPt + ")";

					// Rename the item's parent folder if it's called "New Folder", isn't directly under #RLV and contains exactly 1 object
					if ( (LLViewerFolderType::lookupNewCategoryName(LLFolderType::FT_NONE) == pFolder->getName()) && 
						 (pFolder->getParentUUID() != pRlvRoot->getUUID()) && 
						 (1 == RlvInventory::getDirectDescendentsItemCount(pFolder, LLAssetType::AT_OBJECT)) )
					{
						pFolder->rename(strFolderName);
						pFolder->updateServer(FALSE);
						gInventory.addChangedMask(LLInventoryObserver::LABEL, pFolder->getUUID());
					}
					else
					{
						// "No modify" item with a non-renameable parent: create a new folder named and move the item into it
						LLUUID idFolder = gInventory.createNewCategory(pFolder->getUUID(), LLFolderType::FT_NONE, strFolderName,
						                                               &RlvRenameOnWearObserver::onCategoryCreate, new LLUUID(pItem->getUUID()));
						if (idFolder.notNull())
						{
							// Not using the new 'CreateInventoryCategory' cap so manually invoke the callback
							RlvRenameOnWearObserver::onCategoryCreate(LLSD().with("folder_id", idFolder), new LLUUID(pItem->getUUID()));
						}
					}
				}
			}
		}
	}
	gInventory.notifyObservers();

	delete this;
}
void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params)
{
    bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean();

    llassert(mEditor);
    if (!mEditor)
    {
        return;
    }

    mEditor->setPlainText(use_plain_text_chat_history);

    if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty())
    {
        mUnreadChatSources.insert(chat.mFromName);
        mMoreChatPanel->setVisible(TRUE);
        std::string chatters;
        for (unread_chat_source_t::iterator it = mUnreadChatSources.begin();
                it != mUnreadChatSources.end();)
        {
            chatters += *it;
            if (++it != mUnreadChatSources.end())
            {
                chatters += ", ";
            }
        }
        LLStringUtil::format_map_t args;
        args["SOURCES"] = chatters;

        if (mUnreadChatSources.size() == 1)
        {
            mMoreChatText->setValue(LLTrans::getString("unread_chat_single", args));
        }
        else
        {
            mMoreChatText->setValue(LLTrans::getString("unread_chat_multiple", args));
        }
        S32 height = mMoreChatText->getTextPixelHeight() + 5;
        mMoreChatPanel->reshape(mMoreChatPanel->getRect().getWidth(), height);
    }

    LLColor4 txt_color = LLUIColorTable::instance().getColor("White");
    LLViewerChat::getChatColor(chat,txt_color);
    LLFontGL* fontp = LLViewerChat::getChatFont();
    std::string font_name = LLFontGL::nameFromFont(fontp);
    std::string font_size = LLFontGL::sizeFromFont(fontp);
    LLStyle::Params style_params;
    style_params.color(txt_color);
    style_params.readonly_color(txt_color);
    style_params.font.name(font_name);
    style_params.font.size(font_size);
    style_params.font.style(input_append_params.font.style);

    std::string prefix = chat.mText.substr(0, 4);

    //IRC styled /me messages.
    bool irc_me = prefix == "/me " || prefix == "/me'";

    // Delimiter after a name in header copy/past and in plain text mode
    std::string delimiter = ": ";
    std::string shout = LLTrans::getString("shout");
    std::string whisper = LLTrans::getString("whisper");
    if (chat.mChatType == CHAT_TYPE_SHOUT ||
            chat.mChatType == CHAT_TYPE_WHISPER ||
            chat.mText.compare(0, shout.length(), shout) == 0 ||
            chat.mText.compare(0, whisper.length(), whisper) == 0)
    {
        delimiter = " ";
    }

    // Don't add any delimiter after name in irc styled messages
    if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC)
    {
        delimiter = LLStringUtil::null;
        style_params.font.style = "ITALIC";
    }

    bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
    // We graying out chat history by graying out messages that contains full date in a time string
    if (message_from_log)
    {
        style_params.color(LLColor4::grey);
        style_params.readonly_color(LLColor4::grey);
    }

    if (use_plain_text_chat_history)
    {
        LLStyle::Params timestamp_style(style_params);
        if (!message_from_log)
        {
            LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
            timestamp_style.color(timestamp_color);
            timestamp_style.readonly_color(timestamp_color);
        }
        mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style);

        if (utf8str_trim(chat.mFromName).size() != 0)
        {
            // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
            if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())
            {
// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
                // NOTE-RLVa: we don't need to do any @shownames or @showloc filtering here because we'll already have an existing URL
                std::string url = chat.mURL;
                RLV_ASSERT( (url.empty()) || (std::string::npos != url.find("objectim")) );
                if ( (url.empty()) || (std::string::npos == url.find("objectim")) )
                {
// [/RLVa:KB]
                    // for object IMs, create a secondlife:///app/objectim SLapp
                    /*std::string*/ url = LLViewerChat::getSenderSLURL(chat, args);
// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
                }
// [/RLVa:KB]

                // set the link for the object name to be the objectim SLapp
                // (don't let object names with hyperlinks override our objectim Url)
                LLStyle::Params link_params(style_params);
                LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
                link_params.color = link_color;
                link_params.readonly_color = link_color;
                link_params.is_link = true;
                link_params.link_href = url;

                mEditor->appendText(chat.mFromName + delimiter,
                                    false, link_params);
            }
//			else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
            else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && !chat.mRlvNamesFiltered)
// [/RLVa:KB]
            {
                LLStyle::Params link_params(style_params);
                link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));

                // Add link to avatar's inspector and delimiter to message.
                mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params);
            }
            else
            {
                mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, false, style_params);
            }
        }
    }
    else
    {
        LLView* view = NULL;
        LLInlineViewSegment::Params p;
        p.force_newline = true;
        p.left_pad = mLeftWidgetPad;
        p.right_pad = mRightWidgetPad;

        LLDate new_message_time = LLDate::now();

        if (mLastFromName == chat.mFromName
                && mLastFromID == chat.mFromID
                && mLastMessageTime.notNull()
                && (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
                && mIsLastMessageFromLog == message_from_log)  //distinguish between current and previous chat session's histories
        {
            view = getSeparator();
            p.top_pad = mTopSeparatorPad;
            p.bottom_pad = mBottomSeparatorPad;
        }
        else
        {
            view = getHeader(chat, style_params, args);
            if (mEditor->getText().size() == 0)
                p.top_pad = 0;
            else
                p.top_pad = mTopHeaderPad;
            p.bottom_pad = mBottomHeaderPad;

        }
        p.view = view;

        //Prepare the rect for the view
        LLRect target_rect = mEditor->getDocumentView()->getRect();
        // squeeze down the widget by subtracting padding off left and right
        target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad();
        target_rect.mRight -= mRightWidgetPad;
        view->reshape(target_rect.getWidth(), view->getRect().getHeight());
        view->setOrigin(target_rect.mLeft, view->getRect().mBottom);

        std::string widget_associated_text = "\n[" + chat.mTimeStr + "] ";
        if (utf8str_trim(chat.mFromName).size() != 0 && chat.mFromName != SYSTEM_FROM)
            widget_associated_text += chat.mFromName + delimiter;

        mEditor->appendWidget(p, widget_associated_text, false);
        mLastFromName = chat.mFromName;
        mLastFromID = chat.mFromID;
        mLastMessageTime = new_message_time;
        mIsLastMessageFromLog = message_from_log;
    }

    if (chat.mNotifId.notNull())
    {
        LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId);
        if (notification != NULL)
        {
            LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
                notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history);
            //we can't set follows in xml since it broke toasts behavior
            notify_box->setFollowsLeft();
            notify_box->setFollowsRight();
            notify_box->setFollowsTop();

            ctrl_list_t ctrls = notify_box->getControlPanel()->getCtrlList();
            S32 offset = 0;
            // Children were added by addChild() which uses push_front to insert them into list,
            // so to get buttons in correct order reverse iterator is used (EXT-5906)
            for (ctrl_list_t::reverse_iterator it = ctrls.rbegin(); it != ctrls.rend(); it++)
            {
                LLButton * button = dynamic_cast<LLButton*> (*it);
                if (button != NULL)
                {
                    button->setOrigin( offset,
                                       button->getRect().mBottom);
                    button->setLeftHPad(2 * HPAD);
                    button->setRightHPad(2 * HPAD);
                    // set zero width before perform autoResize()
                    button->setRect(LLRect(button->getRect().mLeft,
                                           button->getRect().mTop, button->getRect().mLeft,
                                           button->getRect().mBottom));
                    button->setAutoResize(true);
                    button->autoResize();
                    offset += HPAD + button->getRect().getWidth();
                    button->setFollowsNone();
                }
            }

            //Prepare the rect for the view
            LLRect target_rect = mEditor->getDocumentView()->getRect();
            // squeeze down the widget by subtracting padding off left and right
            target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad();
            target_rect.mRight -= mRightWidgetPad;
            notify_box->reshape(target_rect.getWidth(),	notify_box->getRect().getHeight());
            notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom);

            LLInlineViewSegment::Params params;
            params.view = notify_box;
            params.left_pad = mLeftWidgetPad;
            params.right_pad = mRightWidgetPad;
            mEditor->appendWidget(params, "\n", false);
        }
    }
    else
    {
        std::string message = irc_me ? chat.mText.substr(3) : chat.mText;


        //MESSAGE TEXT PROCESSING
        //*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010)
        if (use_plain_text_chat_history && gAgentID != chat.mFromID && chat.mFromID.notNull())
        {
            std::string slurl_about = SLURL_APP_AGENT + chat.mFromID.asString() + SLURL_ABOUT;
            if (message.length() > slurl_about.length() &&
                    message.compare(0, slurl_about.length(), slurl_about) == 0)
            {
                message = message.substr(slurl_about.length(), message.length()-1);
            }
        }

        if (irc_me && !use_plain_text_chat_history)
        {
            message = chat.mFromName + message;
        }

        mEditor->appendText(message, FALSE, style_params);
    }

    mEditor->blockUndo();

    // automatically scroll to end when receiving chat from myself
    if (chat.mFromID == gAgentID)
    {
        mEditor->setCursorAndScrollToEnd();
    }
}
Ejemplo n.º 29
0
// Checked: 2010-09-18 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a
void RlvForceWear::done()
{
	// Sanity check - don't go through all the motions below only to find out there's nothing to actually do
	if ( (m_remWearables.empty()) && (m_remAttachments.empty()) && (m_remGestures.empty()) &&
		 (m_addWearables.empty()) && (m_addAttachments.empty()) && (m_addGestures.empty()) )
	{
		return;
	}

	//
	// Process removals
	//

	// Wearables
	if (m_remWearables.size())
	{
		for (std::list<const LLWearable*>::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable)
			gAgent.removeWearable((*itWearable)->getType());
		m_remWearables.clear();
	}

	// Gestures
	if (m_remGestures.size())
	{
		for (S32 idxGesture = 0, cntGesture = m_remGestures.count(); idxGesture < cntGesture; idxGesture++)
		{
			LLViewerInventoryItem* pItem = m_remGestures.get(idxGesture);
			gGestureManager.deactivateGesture(pItem->getUUID());
			gInventory.updateItem(pItem);
			gInventory.notifyObservers();
		}
		m_remGestures.clear();
	}

	// Attachments
	if (m_remAttachments.size())
	{
		// Don't bother with COF if all we're doing is detaching some attachments (keeps people from rebaking on every @remattach=force)
		gMessageSystem->newMessage("ObjectDetach");
		gMessageSystem->nextBlockFast(_PREHASH_AgentData);
		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
		for (std::list<const LLViewerObject*>::const_iterator itAttachObj = m_remAttachments.begin(); 
				itAttachObj != m_remAttachments.end(); ++itAttachObj)
		{
			gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
			gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*itAttachObj)->getLocalID());
		}
		gMessageSystem->sendReliable(gAgent.getRegionHost());

		m_remAttachments.clear();
	}

	//
	// Process additions
	//

	// Process wearables
	if (m_addWearables.size())
	{
		// [See wear_inventory_category_on_avatar_step2()]
		LLWearableHoldingPattern* pWearData = new LLWearableHoldingPattern(TRUE);

		// We need to populate 'pWearData->mFoundList' before doing anything else because (some of) the assets might already be available
		for (addwearables_map_t::const_iterator itAddWearables = m_addWearables.begin(); 
				itAddWearables != m_addWearables.end(); ++itAddWearables)
		{
			const LLInventoryModel::item_array_t& wearItems = itAddWearables->second;

			RLV_VERIFY(1 == wearItems.count());
			if (wearItems.count() > 0)
			{
				LLViewerInventoryItem* pItem = wearItems.get(0);
				if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) )
				{
					LLFoundData* pFound = new LLFoundData(pItem->getUUID(), pItem->getAssetUUID(), pItem->getName(), pItem->getType());
					pWearData->mFoundList.push_front(pFound);
				}
			}
		}

		if (!pWearData->mFoundList.size())
		{
			delete pWearData;
			return;
		}

		// If all the assets are available locally then "pWearData" will be freed *before* the last "gWearableList.getAsset()" call returns
		bool fContinue = true; LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin();
		while ( (fContinue) && (itWearable != pWearData->mFoundList.end()) )
		{
			const LLFoundData* pFound = *itWearable;
			++itWearable;
			fContinue = (itWearable != pWearData->mFoundList.end());
			gWearableList.getAsset(pFound->mAssetID, pFound->mName, pFound->mAssetType, wear_inventory_category_on_avatar_loop, (void*)pWearData);
		}

		m_addWearables.clear();
	}

	// Until LL provides a way for updateCOF to selectively attach add/replace we have to deal with attachments ourselves
	for (addattachments_map_t::const_iterator itAddAttachments = m_addAttachments.begin(); 
			itAddAttachments != m_addAttachments.end(); ++itAddAttachments)
	{
		const LLInventoryModel::item_array_t& wearItems = itAddAttachments->second;
		for (S32 idxItem = 0, cntItem = wearItems.count(); idxItem < cntItem; idxItem++)
		{
			const LLUUID& idItem = wearItems.get(idxItem)->getLinkedUUID();
//			if (gAgentAvatarp->attachmentWasRequested(idItem))
//				continue;
//			gAgentAvatarp->addAttachmentRequest(idItem);

			LLAttachmentsMgr::instance().addAttachment(idItem, itAddAttachments->first & ~ATTACHMENT_ADD, itAddAttachments->first & ATTACHMENT_ADD);
		}
	}
	m_addAttachments.clear();

	// Process gestures
	if (m_addGestures.size())
	{
		gGestureManager.activateGestures(m_addGestures);
		for (S32 idxGesture = 0, cntGesture = m_addGestures.count(); idxGesture < cntGesture; idxGesture++)
			gInventory.updateItem(m_addGestures.get(idxGesture));
		gInventory.notifyObservers();

		m_addGestures.clear();
	}

	// Since RlvForceWear is a singleton now we want to be sure there aren't any leftovers
	RLV_ASSERT( (m_remWearables.empty()) && (m_remAttachments.empty()) && (m_remGestures.empty()) );
	RLV_ASSERT( (m_addWearables.empty()) && (m_addAttachments.empty()) && (m_addGestures.empty()) );
}
Ejemplo n.º 30
0
// Checked: 2010-04-22 (RLVa-1.2.0f) | Modified: RLVa-1.2.0f
void RlvUIEnabler::onToggleShowLoc()
{
    bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC);

    if (LLNavigationBar::instanceExists())
        LLNavigationBar::instance().refreshLocationCtrl();
    if (LLPanelTopInfoBar::instanceExists())
        LLPanelTopInfoBar::instance().update();

    if (!fEnable)
    {
        // Hide the "About Land" floater if it's currently visible
        if (LLFloaterReg::instanceVisible("about_land"))
            LLFloaterReg::hideInstance("about_land");
        // Hide the "Region / Estate" floater if it's currently visible
        if (LLFloaterReg::instanceVisible("region_info"))
            LLFloaterReg::hideInstance("region_info");
        // Hide the "God Tools" floater if it's currently visible
        if (LLFloaterReg::instanceVisible("god_tools"))
            LLFloaterReg::hideInstance("god_tools");

        //
        // Manipulate the teleport history
        //

        // If the last entry in the persistent teleport history matches the current teleport history entry then we should remove it
        LLTeleportHistory* pTpHistory = LLTeleportHistory::getInstance();
        LLTeleportHistoryStorage* pTpHistoryStg = LLTeleportHistoryStorage::getInstance();
        RLV_ASSERT( (pTpHistory) && (pTpHistoryStg) && (pTpHistory->getItems().size() > 0) && (pTpHistory->getCurrentItemIndex() >= 0) );
        if ( (pTpHistory) && (pTpHistory->getItems().size() > 0) && (pTpHistory->getCurrentItemIndex() >= 0) &&
                (pTpHistoryStg) && (pTpHistory->getItems().size() > 0) )
        {
            const LLTeleportHistoryItem& tpItem = pTpHistory->getItems().back();
            const LLTeleportHistoryPersistentItem& tpItemStg = pTpHistoryStg->getItems().back();
            if (pTpHistoryStg->compareByTitleAndGlobalPos(tpItemStg, LLTeleportHistoryPersistentItem(tpItem.mTitle, tpItem.mGlobalPos)))
            {
                // TODO-RLVa: [RLVa-1.2.2] Is there a reason why LLTeleportHistoryStorage::removeItem() doesn't trigger history changed?
                pTpHistoryStg->removeItem(pTpHistoryStg->getItems().size() - 1);
                pTpHistoryStg->mHistoryChangedSignal(-1);
            }
        }

        // Clear the current location in the teleport history
        if (pTpHistory)
            pTpHistory->updateCurrentLocation(gAgent.getPositionGlobal());
    }
    else
    {
        // Reset the current location in the teleport history (also takes care of adding it to the persistent teleport history)
        LLTeleportHistory* pTpHistory = LLTeleportHistory::getInstance();
        if ( (pTpHistory) && (NULL != gAgent.getRegion()) )
            pTpHistory->updateCurrentLocation(gAgent.getPositionGlobal());
    }

    // Start or stop filtering the "About Land" and "Region / Estate" floaters
    if ( (!fEnable) && (!m_ConnFloaterShowLoc.connected()) )
    {
        m_ConnFloaterShowLoc = LLFloaterReg::setValidateCallback(boost::bind(&RlvUIEnabler::filterFloaterShowLoc, this, _1, _2));
        m_ConnPanelShowLoc = LLFloaterSidePanelContainer::setValidateCallback(boost::bind(&RlvUIEnabler::filterPanelShowLoc, this, _1, _2, _3));
    }
    else if ( (fEnable) && (m_ConnFloaterShowLoc.connected()) )
    {
        m_ConnFloaterShowLoc.disconnect();
        m_ConnPanelShowLoc.disconnect();
    }
}