/** * @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 #include #include "llagent.h" #include "llbutton.h" #include "llcombobox.h" #include "llfloaterpathfindingobjects.h" #include "llfloaterreg.h" #include "lllineeditor.h" #include "llnotificationsutil.h" #include "llpathfindinglinkset.h" #include "llpathfindinglinksetlist.h" #include "llpathfindingmanager.h" #include "llsearcheditor.h" #include "llscrolllistitem.h" #include "llsd.h" #include "lltextbase.h" #include "lltextvalidate.h" #include "lluicolortable.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 = LLFloaterReg::getTypedInstance("pathfinding_linksets"); 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) { } LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets() { } bool LLFloaterPathfindingLinksets::postBuild() { mBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingLinksetBeaconColor"); mFilterByName = getChild("filter_by_name"); mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); mFilterByName->setCommitOnFocusLost(true); mFilterByDescription = getChild("filter_by_description"); mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); mFilterByDescription->setCommitOnFocusLost(true); mFilterByLinksetUse = findChild("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("edit_linkset_use"); llassert(mEditLinksetUse != NULL); mEditLinksetUse->clearRows(); mEditLinksetUseUnset = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE)); llassert(mEditLinksetUseUnset != NULL); mEditLinksetUseWalkable = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE)); llassert(mEditLinksetUseWalkable != NULL); mEditLinksetUseStaticObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE)); llassert(mEditLinksetUseStaticObstacle != NULL); mEditLinksetUseDynamicObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE)); llassert(mEditLinksetUseDynamicObstacle != NULL); mEditLinksetUseMaterialVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME)); llassert(mEditLinksetUseMaterialVolume != NULL); mEditLinksetUseExclusionVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME)); llassert(mEditLinksetUseExclusionVolume != NULL); mEditLinksetUseDynamicPhantom = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM)); llassert(mEditLinksetUseDynamicPhantom != NULL); mEditLinksetUse->selectFirstItem(); mLabelWalkabilityCoefficients = findChild("walkability_coefficients_label"); llassert(mLabelWalkabilityCoefficients != NULL); mLabelEditA = findChild("edit_a_label"); llassert(mLabelEditA != NULL); mLabelSuggestedUseA = findChild("suggested_use_a_label"); llassert(mLabelSuggestedUseA != NULL); mEditA = findChild("edit_a_value"); llassert(mEditA != NULL); mEditA->setPrevalidate(LLTextValidate::validateNonNegativeS32); mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueA)); mLabelEditB = findChild("edit_b_label"); llassert(mLabelEditB != NULL); mLabelSuggestedUseB = findChild("suggested_use_b_label"); llassert(mLabelSuggestedUseB != NULL); mEditB = findChild("edit_b_value"); llassert(mEditB != NULL); mEditB->setPrevalidate(LLTextValidate::validateNonNegativeS32); mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueB)); mLabelEditC = findChild("edit_c_label"); llassert(mLabelEditC != NULL); mLabelSuggestedUseC = findChild("suggested_use_c_label"); llassert(mLabelSuggestedUseC != NULL); mEditC = findChild("edit_c_value"); llassert(mEditC != NULL); mEditC->setPrevalidate(LLTextValidate::validateNonNegativeS32); mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueC)); mLabelEditD = findChild("edit_d_label"); llassert(mLabelEditD != NULL); mLabelSuggestedUseD = findChild("suggested_use_d_label"); llassert(mLabelSuggestedUseD != NULL); mEditD = findChild("edit_d_value"); llassert(mEditD != NULL); mEditD->setPrevalidate(LLTextValidate::validateNonNegativeS32); mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueD)); mApplyEditsButton = findChild("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(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(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(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(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; } 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(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(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(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(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(atoi(aString.c_str())); S32 bValue = static_cast(atoi(bString.c_str())); S32 cValue = static_cast(atoi(cString.c_str())); S32 dValue = static_cast(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; }