Files
SingularityViewer/indra/newview/llfloaterpathfindinglinksets.cpp

807 lines
27 KiB
C++

/**
* @file llfloaterpathfindinglinksets.cpp
* @brief "Pathfinding linksets" floater, allowing manipulation of the linksets on the current region.
* @author Stinson@lindenlab.com
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterpathfindinglinksets.h"
#include <string>
#include <boost/bind.hpp>
#include "llagent.h"
#include "llbutton.h"
#include "llcombobox.h"
#include "llfloaterpathfindingobjects.h"
#include "lllineeditor.h"
#include "llnotificationsutil.h"
#include "llpathfindinglinkset.h"
#include "llpathfindinglinksetlist.h"
#include "llpathfindingmanager.h"
#include "llscrolllistitem.h"
#include "llsd.h"
#include "lltextbox.h"
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluictrl.h"
#include "v3math.h"
#include "v4color.h"
#define XUI_LINKSET_USE_NONE 0
#define XUI_LINKSET_USE_WALKABLE 1
#define XUI_LINKSET_USE_STATIC_OBSTACLE 2
#define XUI_LINKSET_USE_DYNAMIC_OBSTACLE 3
#define XUI_LINKSET_USE_MATERIAL_VOLUME 4
#define XUI_LINKSET_USE_EXCLUSION_VOLUME 5
#define XUI_LINKSET_USE_DYNAMIC_PHANTOM 6
//---------------------------------------------------------------------------
// LLFloaterPathfindingLinksets
//---------------------------------------------------------------------------
void LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects()
{
LLFloaterPathfindingLinksets* linksetsFloater = getInstance();
linksetsFloater->clearFilters();
linksetsFloater->showFloaterWithSelectionObjects();
}
LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
: LLFloaterPathfindingObjects(/*pSeed*/),
mFilterByName(NULL),
mFilterByDescription(NULL),
mFilterByLinksetUse(NULL),
mEditLinksetUse(NULL),
mEditLinksetUseWalkable(NULL),
mEditLinksetUseStaticObstacle(NULL),
mEditLinksetUseDynamicObstacle(NULL),
mEditLinksetUseMaterialVolume(NULL),
mEditLinksetUseExclusionVolume(NULL),
mEditLinksetUseDynamicPhantom(NULL),
mLabelWalkabilityCoefficients(NULL),
mLabelEditA(NULL),
mLabelSuggestedUseA(NULL),
mEditA(NULL),
mLabelEditB(NULL),
mLabelSuggestedUseB(NULL),
mEditB(NULL),
mLabelEditC(NULL),
mLabelSuggestedUseC(NULL),
mEditC(NULL),
mLabelEditD(NULL),
mLabelSuggestedUseD(NULL),
mEditD(NULL),
mApplyEditsButton(NULL),
mBeaconColor(),
mPreviousValueA(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
mPreviousValueB(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
mPreviousValueC(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
mPreviousValueD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE)
{
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_pathfinding_linksets.xml");
}
LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets()
{
}
BOOL LLFloaterPathfindingLinksets::postBuild()
{
mBeaconColor = LLUI::sColorsGroup->getColor("PathfindingLinksetBeaconColor");
mFilterByName = findChild<LLLineEditor>("filter_by_name");
llassert(mFilterByName != NULL);
mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
mFilterByName->setSelectAllonFocusReceived(true);
mFilterByName->setCommitOnFocusLost(true);
mFilterByDescription = findChild<LLLineEditor>("filter_by_description");
llassert(mFilterByDescription != NULL);
mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
mFilterByDescription->setSelectAllonFocusReceived(true);
mFilterByDescription->setCommitOnFocusLost(true);
mFilterByLinksetUse = findChild<LLComboBox>("filter_by_linkset_use");
llassert(mFilterByLinksetUse != NULL);
mFilterByLinksetUse->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this));
mEditLinksetUse = findChild<LLComboBox>("edit_linkset_use");
llassert(mEditLinksetUse != NULL);
mEditLinksetUse->clearRows();
mEditLinksetUseUnset = mEditLinksetUse->add(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE);
llassert(mEditLinksetUseUnset != NULL);
mEditLinksetUseWalkable = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE);
llassert(mEditLinksetUseWalkable != NULL);
mEditLinksetUseStaticObstacle = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE);
llassert(mEditLinksetUseStaticObstacle != NULL);
mEditLinksetUseDynamicObstacle = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE);
llassert(mEditLinksetUseDynamicObstacle != NULL);
mEditLinksetUseMaterialVolume = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME);
llassert(mEditLinksetUseMaterialVolume != NULL);
mEditLinksetUseExclusionVolume = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME);
llassert(mEditLinksetUseExclusionVolume != NULL);
mEditLinksetUseDynamicPhantom = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM);
llassert(mEditLinksetUseDynamicPhantom != NULL);
mEditLinksetUse->selectFirstItem();
mLabelWalkabilityCoefficients = findChild<LLTextBox>("walkability_coefficients_label");
llassert(mLabelWalkabilityCoefficients != NULL);
mLabelEditA = findChild<LLTextBox>("edit_a_label");
llassert(mLabelEditA != NULL);
mLabelSuggestedUseA = findChild<LLTextBox>("suggested_use_a_label");
llassert(mLabelSuggestedUseA != NULL);
mEditA = findChild<LLLineEditor>("edit_a_value");
llassert(mEditA != NULL);
mEditA->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueA));
mLabelEditB = findChild<LLTextBox>("edit_b_label");
llassert(mLabelEditB != NULL);
mLabelSuggestedUseB = findChild<LLTextBox>("suggested_use_b_label");
llassert(mLabelSuggestedUseB != NULL);
mEditB = findChild<LLLineEditor>("edit_b_value");
llassert(mEditB != NULL);
mEditB->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueB));
mLabelEditC = findChild<LLTextBox>("edit_c_label");
llassert(mLabelEditC != NULL);
mLabelSuggestedUseC = findChild<LLTextBox>("suggested_use_c_label");
llassert(mLabelSuggestedUseC != NULL);
mEditC = findChild<LLLineEditor>("edit_c_value");
llassert(mEditC != NULL);
mEditC->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueC));
mLabelEditD = findChild<LLTextBox>("edit_d_label");
llassert(mLabelEditD != NULL);
mLabelSuggestedUseD = findChild<LLTextBox>("suggested_use_d_label");
llassert(mLabelSuggestedUseD != NULL);
mEditD = findChild<LLLineEditor>("edit_d_value");
llassert(mEditD != NULL);
mEditD->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueD));
mApplyEditsButton = findChild<LLButton>("apply_edit_values");
llassert(mApplyEditsButton != NULL);
mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this));
return LLFloaterPathfindingObjects::postBuild();
}
void LLFloaterPathfindingLinksets::requestGetObjects()
{
LLPathfindingManager::getInstance()->requestGetLinksets(getNewRequestId(), boost::bind(&LLFloaterPathfindingLinksets::handleNewObjectList, this, _1, _2, _3));
}
void LLFloaterPathfindingLinksets::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr)
{
llassert(pObjectListPtr != NULL);
llassert(!pObjectListPtr->isEmpty());
std::string nameFilter = mFilterByName->getText();
std::string descriptionFilter = mFilterByDescription->getText();
LLPathfindingLinkset::ELinksetUse linksetUseFilter = getFilterLinksetUse();
bool isFilteringName = !nameFilter.empty();
bool isFilteringDescription = !descriptionFilter.empty();
bool isFilteringLinksetUse = (linksetUseFilter != LLPathfindingLinkset::kUnknown);
const LLVector3& avatarPosition = gAgent.getPositionAgent();
if (isFilteringName || isFilteringDescription || isFilteringLinksetUse)
{
LLStringUtil::toUpper(nameFilter);
LLStringUtil::toUpper(descriptionFilter);
for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
{
const LLPathfindingObjectPtr objectPtr = objectIter->second;
const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
llassert(linksetPtr != NULL);
std::string linksetName = (linksetPtr->isTerrain() ? getString("linkset_terrain_name") : linksetPtr->getName());
std::string linksetDescription = linksetPtr->getDescription();
LLStringUtil::toUpper(linksetName);
LLStringUtil::toUpper(linksetDescription);
if ((!isFilteringName || (linksetName.find(nameFilter) != std::string::npos)) &&
(!isFilteringDescription || (linksetDescription.find(descriptionFilter) != std::string::npos)) &&
(!isFilteringLinksetUse || (linksetPtr->getLinksetUse() == linksetUseFilter)))
{
LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition);
addObjectToScrollList(objectPtr, scrollListItemData);
}
}
}
else
{
for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
{
const LLPathfindingObjectPtr objectPtr = objectIter->second;
const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
llassert(linksetPtr != NULL);
LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition);
addObjectToScrollList(objectPtr, scrollListItemData);
}
}
}
void LLFloaterPathfindingLinksets::updateControlsOnScrollListChange()
{
LLFloaterPathfindingObjects::updateControlsOnScrollListChange();
updateEditFieldValues();
updateStateOnEditFields();
updateStateOnEditLinksetUse();
}
S32 LLFloaterPathfindingLinksets::getNameColumnIndex() const
{
return 0;
}
S32 LLFloaterPathfindingLinksets::getOwnerNameColumnIndex() const
{
return 2;
}
std::string LLFloaterPathfindingLinksets::getOwnerName(const LLPathfindingObject *pObject) const
{
return (pObject->hasOwner()
? (pObject->hasOwnerName()
? (pObject->isGroupOwned()
? (pObject->getOwnerName() + " " + getString("linkset_owner_group"))
: pObject->getOwnerName())
: getString("linkset_owner_loading"))
: getString("linkset_owner_unknown"));
}
const LLColor4 &LLFloaterPathfindingLinksets::getBeaconColor() const
{
return mBeaconColor;
}
LLPathfindingObjectListPtr LLFloaterPathfindingLinksets::getEmptyObjectList() const
{
LLPathfindingObjectListPtr objectListPtr(new LLPathfindingLinksetList());
return objectListPtr;
}
void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingObjectListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD)
{
LLPathfindingManager::getInstance()->requestSetLinksets(getNewRequestId(), pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleUpdateObjectList, this, _1, _2, _3));
}
void LLFloaterPathfindingLinksets::onApplyAllFilters()
{
rebuildObjectsScrollList();
}
void LLFloaterPathfindingLinksets::onClearFiltersClicked()
{
clearFilters();
rebuildObjectsScrollList();
}
void LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl, LLSD &pPreviousValue)
{
LLLineEditor *pLineEditor = static_cast<LLLineEditor *>(pUICtrl);
llassert(pLineEditor != NULL);
const std::string &valueString = pLineEditor->getText();
S32 intValue;
LLSD value;
bool doResetValue = false;
if (valueString.empty())
{
value = pPreviousValue;
doResetValue = true;
}
else if (LLStringUtil::convertToS32(valueString, intValue))
{
doResetValue = ((intValue < LLPathfindingLinkset::MIN_WALKABILITY_VALUE) || (intValue > LLPathfindingLinkset::MAX_WALKABILITY_VALUE));
value = LLSD(llclamp(intValue, LLPathfindingLinkset::MIN_WALKABILITY_VALUE, LLPathfindingLinkset::MAX_WALKABILITY_VALUE));
}
else
{
value = LLSD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE);
doResetValue = true;
}
if (doResetValue)
{
pLineEditor->setValue(value);
}
pPreviousValue = value;
}
void LLFloaterPathfindingLinksets::onApplyChangesClicked()
{
applyEdit();
}
void LLFloaterPathfindingLinksets::clearFilters()
{
mFilterByName->clear();
mFilterByDescription->clear();
setFilterLinksetUse(LLPathfindingLinkset::kUnknown);
}
void LLFloaterPathfindingLinksets::updateEditFieldValues()
{
int numSelectedObjects = getNumSelectedObjects();
if (numSelectedObjects <= 0)
{
mEditLinksetUse->selectFirstItem();
mEditA->clear();
mEditB->clear();
mEditC->clear();
mEditD->clear();
}
else
{
LLPathfindingObjectPtr firstSelectedObjectPtr = getFirstSelectedObject();
llassert(firstSelectedObjectPtr != NULL);
const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(firstSelectedObjectPtr.get());
setEditLinksetUse(linkset->getLinksetUse());
mPreviousValueA = LLSD(linkset->getWalkabilityCoefficientA());
mPreviousValueB = LLSD(linkset->getWalkabilityCoefficientB());
mPreviousValueC = LLSD(linkset->getWalkabilityCoefficientC());
mPreviousValueD = LLSD(linkset->getWalkabilityCoefficientD());
mEditA->setValue(mPreviousValueA);
mEditB->setValue(mPreviousValueB);
mEditC->setValue(mPreviousValueC);
mEditD->setValue(mPreviousValueD);
}
}
LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListItemData(const LLPathfindingLinkset *pLinksetPtr, const LLVector3 &pAvatarPosition) const
{
llassert(pLinksetPtr != NULL);
LLSD columns = LLSD::emptyArray();
if (pLinksetPtr->isTerrain())
{
columns[0]["column"] = "name";
columns[0]["value"] = getString("linkset_terrain_name");
columns[1]["column"] = "description";
columns[1]["value"] = getString("linkset_terrain_description");
columns[2]["column"] = "owner";
columns[2]["value"] = getString("linkset_terrain_owner");
columns[3]["column"] = "scripted";
columns[3]["value"] = getString("linkset_terrain_scripted");
columns[4]["column"] = "land_impact";
columns[4]["value"] = getString("linkset_terrain_land_impact");
columns[5]["column"] = "dist_from_you";
columns[5]["value"] = getString("linkset_terrain_dist_from_you");
}
else
{
columns[0]["column"] = "name";
columns[0]["value"] = pLinksetPtr->getName();
columns[1]["column"] = "description";
columns[1]["value"] = pLinksetPtr->getDescription();
columns[2]["column"] = "owner";
columns[2]["value"] = getOwnerName(pLinksetPtr);
columns[3]["column"] = "scripted";
columns[3]["value"] = (pLinksetPtr->hasIsScripted()
? (pLinksetPtr->isScripted()
? getString("linkset_is_scripted")
: getString("linkset_is_not_scripted"))
: getString("linkset_is_unknown_scripted"));
columns[4]["column"] = "land_impact";
columns[4]["value"] = llformat("%1d", pLinksetPtr->getLandImpact());
columns[5]["column"] = "dist_from_you";
columns[5]["value"] = llformat("%1.0f m", dist_vec(pAvatarPosition, pLinksetPtr->getLocation()));
}
columns[6]["column"] = "linkset_use";
std::string linksetUse = getLinksetUseString(pLinksetPtr->getLinksetUse());
if (pLinksetPtr->isTerrain())
{
linksetUse += (" " + getString("linkset_is_terrain"));
}
else if (!pLinksetPtr->isModifiable() && pLinksetPtr->canBeVolume())
{
linksetUse += (" " + getString("linkset_is_restricted_state"));
}
else if (pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
{
linksetUse += (" " + getString("linkset_is_non_volume_state"));
}
else if (!pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
{
linksetUse += (" " + getString("linkset_is_restricted_non_volume_state"));
}
columns[6]["value"] = linksetUse;
columns[7]["column"] = "a_percent";
columns[7]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientA());
columns[8]["column"] = "b_percent";
columns[8]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientB());
columns[9]["column"] = "c_percent";
columns[9]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientC());
columns[10]["column"] = "d_percent";
columns[10]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientD());
return columns;
}
/* Singu-Note: Unused function
LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListData(const std::string &pLabel, S32 pValue) const
{
LLSD columns;
columns[0]["column"] = "name";
columns[0]["value"] = pLabel;
columns[0]["font"] = "SANSSERIF";
LLSD element;
element["value"] = pValue;
element["column"] = columns;
return element;
}
*/
bool LLFloaterPathfindingLinksets::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
bool isShowWarning = false;
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
{
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
isShowWarning = linksetList->isShowUnmodifiablePhantomWarning(pLinksetUse);
}
}
return isShowWarning;
}
bool LLFloaterPathfindingLinksets::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
bool isShowWarning = false;
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
{
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
isShowWarning = linksetList->isShowPhantomToggleWarning(pLinksetUse);
}
}
return isShowWarning;
}
bool LLFloaterPathfindingLinksets::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
bool isShowWarning = false;
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
{
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
isShowWarning = linksetList->isShowCannotBeVolumeWarning(pLinksetUse);
}
}
return isShowWarning;
}
void LLFloaterPathfindingLinksets::updateStateOnEditFields()
{
int numSelectedItems = getNumSelectedObjects();
bool isEditEnabled = (numSelectedItems > 0);
mEditLinksetUse->setEnabled(isEditEnabled);
mLabelWalkabilityCoefficients->setEnabled(isEditEnabled);
mLabelEditA->setEnabled(isEditEnabled);
mLabelEditB->setEnabled(isEditEnabled);
mLabelEditC->setEnabled(isEditEnabled);
mLabelEditD->setEnabled(isEditEnabled);
mLabelSuggestedUseA->setEnabled(isEditEnabled);
mLabelSuggestedUseB->setEnabled(isEditEnabled);
mLabelSuggestedUseC->setEnabled(isEditEnabled);
mLabelSuggestedUseD->setEnabled(isEditEnabled);
mEditA->setEnabled(isEditEnabled);
mEditB->setEnabled(isEditEnabled);
mEditC->setEnabled(isEditEnabled);
mEditD->setEnabled(isEditEnabled);
mApplyEditsButton->setEnabled(isEditEnabled && (getMessagingState() == kMessagingComplete));
}
void LLFloaterPathfindingLinksets::updateStateOnEditLinksetUse()
{
BOOL useWalkable = FALSE;
BOOL useStaticObstacle = FALSE;
BOOL useDynamicObstacle = FALSE;
BOOL useMaterialVolume = FALSE;
BOOL useExclusionVolume = FALSE;
BOOL useDynamicPhantom = FALSE;
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
linksetList->determinePossibleStates(useWalkable, useStaticObstacle, useDynamicObstacle, useMaterialVolume, useExclusionVolume, useDynamicPhantom);
}
mEditLinksetUseWalkable->setEnabled(useWalkable);
mEditLinksetUseStaticObstacle->setEnabled(useStaticObstacle);
mEditLinksetUseDynamicObstacle->setEnabled(useDynamicObstacle);
mEditLinksetUseMaterialVolume->setEnabled(useMaterialVolume);
mEditLinksetUseExclusionVolume->setEnabled(useExclusionVolume);
mEditLinksetUseDynamicPhantom->setEnabled(useDynamicPhantom);
}
void LLFloaterPathfindingLinksets::applyEdit()
{
LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
bool showPhantomToggleWarning = isShowPhantomToggleWarning(linksetUse);
bool showUnmodifiablePhantomWarning = isShowUnmodifiablePhantomWarning(linksetUse);
bool showCannotBeVolumeWarning = isShowCannotBeVolumeWarning(linksetUse);
if (showPhantomToggleWarning || showUnmodifiablePhantomWarning || showCannotBeVolumeWarning)
{
LLPathfindingLinkset::ELinksetUse restrictedLinksetUse = LLPathfindingLinkset::getLinksetUseWithToggledPhantom(linksetUse);
LLSD substitutions;
substitutions["REQUESTED_TYPE"] = getLinksetUseString(linksetUse);
substitutions["RESTRICTED_TYPE"] = getLinksetUseString(restrictedLinksetUse);
// Build one of the following notifications names
// - PathfindingLinksets_WarnOnPhantom
// - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted
// - PathfindingLinksets_WarnOnPhantom_MismatchOnVolume
// - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume
// - PathfindingLinksets_MismatchOnRestricted
// - PathfindingLinksets_MismatchOnVolume
// - PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume
std::string notificationName = "PathfindingLinksets";
if (showPhantomToggleWarning)
{
notificationName += "_WarnOnPhantom";
}
if (showUnmodifiablePhantomWarning)
{
notificationName += "_MismatchOnRestricted";
}
if (showCannotBeVolumeWarning)
{
notificationName += "_MismatchOnVolume";
}
LLNotificationsUtil::add(notificationName, substitutions, LLSD(), boost::bind(&LLFloaterPathfindingLinksets::handleApplyEdit, this, _1, _2));
}
else
{
doApplyEdit();
}
}
void LLFloaterPathfindingLinksets::handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse)
{
if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
{
doApplyEdit();
}
}
void LLFloaterPathfindingLinksets::doApplyEdit()
{
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
const std::string &aString = mEditA->getText();
const std::string &bString = mEditB->getText();
const std::string &cString = mEditC->getText();
const std::string &dString = mEditD->getText();
S32 aValue = static_cast<S32>(atoi(aString.c_str()));
S32 bValue = static_cast<S32>(atoi(bString.c_str()));
S32 cValue = static_cast<S32>(atoi(cString.c_str()));
S32 dValue = static_cast<S32>(atoi(dString.c_str()));
requestSetLinksets(selectedObjects, linksetUse, aValue, bValue, cValue, dValue);
}
}
std::string LLFloaterPathfindingLinksets::getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
std::string linksetUse;
switch (pLinksetUse)
{
case LLPathfindingLinkset::kWalkable :
linksetUse = getString("linkset_use_walkable");
break;
case LLPathfindingLinkset::kStaticObstacle :
linksetUse = getString("linkset_use_static_obstacle");
break;
case LLPathfindingLinkset::kDynamicObstacle :
linksetUse = getString("linkset_use_dynamic_obstacle");
break;
case LLPathfindingLinkset::kMaterialVolume :
linksetUse = getString("linkset_use_material_volume");
break;
case LLPathfindingLinkset::kExclusionVolume :
linksetUse = getString("linkset_use_exclusion_volume");
break;
case LLPathfindingLinkset::kDynamicPhantom :
linksetUse = getString("linkset_use_dynamic_phantom");
break;
case LLPathfindingLinkset::kUnknown :
default :
linksetUse = getString("linkset_use_dynamic_obstacle");
llassert(0);
break;
}
return linksetUse;
}
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getFilterLinksetUse() const
{
return convertToLinksetUse(mFilterByLinksetUse->getValue());
}
void LLFloaterPathfindingLinksets::setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
{
mFilterByLinksetUse->setValue(convertToXuiValue(pLinksetUse));
}
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getEditLinksetUse() const
{
return convertToLinksetUse(mEditLinksetUse->getValue());
}
void LLFloaterPathfindingLinksets::setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
{
mEditLinksetUse->setValue(convertToXuiValue(pLinksetUse));
}
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::convertToLinksetUse(LLSD pXuiValue) const
{
LLPathfindingLinkset::ELinksetUse linkUse;
switch (pXuiValue.asInteger())
{
case XUI_LINKSET_USE_NONE :
linkUse = LLPathfindingLinkset::kUnknown;
break;
case XUI_LINKSET_USE_WALKABLE :
linkUse = LLPathfindingLinkset::kWalkable;
break;
case XUI_LINKSET_USE_STATIC_OBSTACLE :
linkUse = LLPathfindingLinkset::kStaticObstacle;
break;
case XUI_LINKSET_USE_DYNAMIC_OBSTACLE :
linkUse = LLPathfindingLinkset::kDynamicObstacle;
break;
case XUI_LINKSET_USE_MATERIAL_VOLUME :
linkUse = LLPathfindingLinkset::kMaterialVolume;
break;
case XUI_LINKSET_USE_EXCLUSION_VOLUME :
linkUse = LLPathfindingLinkset::kExclusionVolume;
break;
case XUI_LINKSET_USE_DYNAMIC_PHANTOM :
linkUse = LLPathfindingLinkset::kDynamicPhantom;
break;
default :
linkUse = LLPathfindingLinkset::kUnknown;
llassert(0);
break;
}
return linkUse;
}
LLSD LLFloaterPathfindingLinksets::convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
LLSD xuiValue;
switch (pLinksetUse)
{
case LLPathfindingLinkset::kUnknown :
xuiValue = XUI_LINKSET_USE_NONE;
break;
case LLPathfindingLinkset::kWalkable :
xuiValue = XUI_LINKSET_USE_WALKABLE;
break;
case LLPathfindingLinkset::kStaticObstacle :
xuiValue = XUI_LINKSET_USE_STATIC_OBSTACLE;
break;
case LLPathfindingLinkset::kDynamicObstacle :
xuiValue = XUI_LINKSET_USE_DYNAMIC_OBSTACLE;
break;
case LLPathfindingLinkset::kMaterialVolume :
xuiValue = XUI_LINKSET_USE_MATERIAL_VOLUME;
break;
case LLPathfindingLinkset::kExclusionVolume :
xuiValue = XUI_LINKSET_USE_EXCLUSION_VOLUME;
break;
case LLPathfindingLinkset::kDynamicPhantom :
xuiValue = XUI_LINKSET_USE_DYNAMIC_PHANTOM;
break;
default :
xuiValue = XUI_LINKSET_USE_NONE;
llassert(0);
break;
}
return xuiValue;
}