diff options
Diffstat (limited to 'indra/newview/llfloatereditenvironmentbase.cpp')
-rw-r--r-- | indra/newview/llfloatereditenvironmentbase.cpp | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp new file mode 100644 index 0000000000..2a38f18b73 --- /dev/null +++ b/indra/newview/llfloatereditenvironmentbase.cpp @@ -0,0 +1,479 @@ +/** + * @file llfloatereditenvironmentbase.cpp + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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 "llfloatereditenvironmentbase.h" + +#include <boost/make_shared.hpp> + +// libs +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llfilepicker.h" +#include "llsettingspicker.h" +#include "llviewerparcelmgr.h" + +// newview +#include "llsettingssky.h" +#include "llsettingswater.h" + +#include "llenvironment.h" +#include "llagent.h" +#include "llparcel.h" + +#include "llsettingsvo.h" +#include "llinventorymodel.h" + +namespace +{ + const std::string ACTION_APPLY_LOCAL("apply_local"); + const std::string ACTION_APPLY_PARCEL("apply_parcel"); + const std::string ACTION_APPLY_REGION("apply_region"); +} + +//========================================================================= +const std::string LLFloaterEditEnvironmentBase::KEY_INVENTORY_ID("inventory_id"); + + +//========================================================================= + +class LLFixedSettingCopiedCallback : public LLInventoryCallback +{ +public: + LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {} + + virtual void fire(const LLUUID& inv_item_id) + { + if (!mHandle.isDead()) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); + if (item) + { + LLFloaterEditEnvironmentBase* floater = (LLFloaterEditEnvironmentBase*)mHandle.get(); + floater->onInventoryCreated(item->getAssetUUID(), inv_item_id); + } + } + } + +private: + LLHandle<LLFloater> mHandle; +}; + +//========================================================================= +LLFloaterEditEnvironmentBase::LLFloaterEditEnvironmentBase(const LLSD &key) : + LLFloater(key), + mInventoryId(), + mInventoryItem(nullptr), + mIsDirty(false), + mCanCopy(false), + mCanMod(false), + mCanTrans(false), + mCanSave(false) +{ +} + +LLFloaterEditEnvironmentBase::~LLFloaterEditEnvironmentBase() +{ +} + +void LLFloaterEditEnvironmentBase::onFocusReceived() +{ + if (isInVisibleChain()) + { + updateEditEnvironment(); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); + } +} + +void LLFloaterEditEnvironmentBase::onFocusLost() +{ +} + +void LLFloaterEditEnvironmentBase::loadInventoryItem(const LLUUID &inventoryId, bool can_trans) +{ + if (inventoryId.isNull()) + { + mInventoryItem = nullptr; + mInventoryId.setNull(); + mCanMod = true; + mCanCopy = true; + mCanTrans = true; + return; + } + + mInventoryId = inventoryId; + LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; + mInventoryItem = gInventory.getItem(mInventoryId); + + if (!mInventoryItem) + { + LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; + LLNotificationsUtil::add("CantFindInvItem"); + closeFloater(); + + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + if (mInventoryItem->getAssetUUID().isNull()) + { + LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; + LLNotificationsUtil::add("UnableEditItem"); + closeFloater(); + + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + mCanSave = true; + mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); + mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); + mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + + mExpectingAssetId = mInventoryItem->getAssetUUID(); + LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), + [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); +} + + +void LLFloaterEditEnvironmentBase::checkAndConfirmSettingsLoss(LLFloaterEditEnvironmentBase::on_confirm_fn cb) +{ + if (isDirty()) + { + LLSD args(LLSDMap("TYPE", getEditSettings()->getSettingsType()) + ("NAME", getEditSettings()->getName())); + + // create and show confirmation textbox + LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), + [cb](const LLSD¬if, const LLSD&resp) + { + S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); + if (opt == 0) + cb(); + }); + } + else if (cb) + { + cb(); + } +} + +void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) +{ + if (asset_id != mExpectingAssetId) + { + LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL; + return; + } + mExpectingAssetId.setNull(); + clearDirtyFlag(); + + if (!settings || status) + { + LLSD args; + args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown"; + LLNotificationsUtil::add("FailedToFindSettings", args); + closeFloater(); + return; + } + + if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE)) + { + mCanSave = false; + mCanCopy = false; + mCanMod = false; + mCanTrans = false; + } + else + { + if (mInventoryItem) + settings->setName(mInventoryItem->getName()); + + if (mCanCopy) + settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); + else + settings->setFlag(LLSettingsBase::FLAG_NOCOPY); + + if (mCanMod) + settings->clearFlag(LLSettingsBase::FLAG_NOMOD); + else + settings->setFlag(LLSettingsBase::FLAG_NOMOD); + + if (mCanTrans) + settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); + else + settings->setFlag(LLSettingsBase::FLAG_NOTRANS); + } + + setEditSettingsAndUpdate(settings); +} + +void LLFloaterEditEnvironmentBase::onButtonImport() +{ + checkAndConfirmSettingsLoss([this](){ doImportFromDisk(); }); +} + +void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + std::string settings_name = response["message"].asString(); + + LLInventoryObject::correctInventoryName(settings_name); + if (settings_name.empty()) + { + // Ideally notification should disable 'OK' button if name won't fit our requirements, + // for now either display notification, or use some default name + settings_name = "Unnamed"; + } + + if (mCanMod) + { + doApplyCreateNewInventory(settings_name, settings); + } + else if (mInventoryItem) + { + const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + LLUUID parent_id = mInventoryItem->getParentUUID(); + if (marketplacelistings_id == parent_id) + { + parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); + } + + LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle()); + copy_inventory_item( + gAgent.getID(), + mInventoryItem->getPermissions().getOwner(), + mInventoryItem->getUUID(), + parent_id, + settings_name, + cb); + } + else + { + LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL; + } + } +} + +void LLFloaterEditEnvironmentBase::onClickCloseBtn(bool app_quitting) +{ + if (!app_quitting) + checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); }); + else + closeFloater(); +} + +void LLFloaterEditEnvironmentBase::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings) +{ + if (mInventoryItem) + { + LLUUID parent_id = mInventoryItem->getParentUUID(); + U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); + LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } + else + { + LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); + // This method knows what sort of settings object to create. + LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } +} + +void LLFloaterEditEnvironmentBase::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings) +{ + LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL; + if (mInventoryId.isNull()) + { + LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } + else + { + LLSettingsVOBase::updateInventoryItem(settings, mInventoryId, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); + } +} + +void LLFloaterEditEnvironmentBase::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings) +{ + U32 flags(0); + + if (mInventoryItem) + { + if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) + flags |= LLSettingsBase::FLAG_NOMOD; + if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + flags |= LLSettingsBase::FLAG_NOTRANS; + } + + flags |= settings->getFlags(); + settings->setFlag(flags); + + if (where == ACTION_APPLY_LOCAL) + { + settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings); + } + else if (where == ACTION_APPLY_PARCEL) + { + LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); + + if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) + { + LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL; + LLNotificationsUtil::add("WLParcelApplyFail"); + return; + } + + if (mInventoryItem && !isDirty()) + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); + } + else if (settings->getSettingsType() == "sky") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1); + } + else if (settings->getSettingsType() == "water") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1); + } + else if (settings->getSettingsType() == "day") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsDay>(settings), -1, -1); + } + } + else if (where == ACTION_APPLY_REGION) + { + if (mInventoryItem && !isDirty()) + { + LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); + } + else if (settings->getSettingsType() == "sky") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1); + } + else if (settings->getSettingsType() == "water") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1); + } + else if (settings->getSettingsType() == "day") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsDay>(settings), -1, -1); + } + } + else + { + LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; + return; + } + +} + +void LLFloaterEditEnvironmentBase::doCloseInventoryFloater(bool quitting) +{ + LLFloater* floaterp = mInventoryFloater.get(); + + if (floaterp) + { + floaterp->closeFloater(quitting); + } +} + +void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; + + if (inventory_id.isNull() || !results["success"].asBoolean()) + { + LLNotificationsUtil::add("CantCreateInventory"); + return; + } + onInventoryCreated(asset_id, inventory_id); +} + +void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id) +{ + bool can_trans = true; + if (mInventoryItem) + { + LLPermissions perms = mInventoryItem->getPermissions(); + + LLInventoryItem *created_item = gInventory.getItem(mInventoryId); + + if (created_item) + { + can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID()); + created_item->setPermissions(perms); + created_item->updateServer(false); + } + } + + clearDirtyFlag(); + setFocus(TRUE); // Call back the focus... + loadInventoryItem(inventory_id, can_trans); +} + +void LLFloaterEditEnvironmentBase::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; + + clearDirtyFlag(); + if (inventory_id != mInventoryId) + { + loadInventoryItem(inventory_id); + } +} + +void LLFloaterEditEnvironmentBase::onPanelDirtyFlagChanged(bool value) +{ + if (value) + setDirtyFlag(); +} + +//------------------------------------------------------------------------- +bool LLFloaterEditEnvironmentBase::canUseInventory() const +{ + return LLEnvironment::instance().isInventoryEnabled(); +} + +bool LLFloaterEditEnvironmentBase::canApplyRegion() const +{ + return gAgent.canManageEstate(); +} + +bool LLFloaterEditEnvironmentBase::canApplyParcel() const +{ + return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); +} + +//========================================================================= |