/** * @file llfloaterproperties.cpp * @brief A floater which shows an inventory item's properties. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, 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 "llfloaterproperties.h" #include #include #include "llcachename.h" #include "llavatarnamecache.h" #include "lldbstrings.h" #include "llfloaterreg.h" #include "llagent.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llavataractions.h" #include "llinventorydefines.h" #include "llinventoryobserver.h" #include "llinventorymodel.h" #include "lllineeditor.h" //#include "llspinctrl.h" #include "llradiogroup.h" #include "llresmgr.h" #include "roles_constants.h" #include "llselectmgr.h" #include "lltextbox.h" #include "lltrans.h" #include "lluiconstants.h" #include "llviewerinventory.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llgroupactions.h" #include "lluictrlfactory.h" // [RLVa:KB] - Checked: RLVa-2.0.1 #include "rlvactions.h" #include "rlvcommon.h" // [/RLVa:KB] #include "llviewernetwork.h" // For OpenSim export perms #include "llexperiencecache.h" #include "llslurl.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLPropertiesObserver // // helper class to watch the inventory. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Ugh. This can't be a singleton because it needs to remove itself // from the inventory observer list when destroyed, which could // happen after gInventory has already been destroyed if a singleton. // Instead, do our own ref counting and create / destroy it as needed class LLPropertiesObserver : public LLInventoryObserver { public: LLPropertiesObserver(LLFloaterProperties* floater) : mFloater(floater) { gInventory.addObserver(this); } virtual ~LLPropertiesObserver() { gInventory.removeObserver(this); } virtual void changed(U32 mask); private: LLFloaterProperties* mFloater; // Not a handle because LLFloaterProperties is managing LLPropertiesObserver }; void LLPropertiesObserver::changed(U32 mask) { // if there's a change we're interested in. if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0) { mFloater->dirty(); } } ///---------------------------------------------------------------------------- /// Class LLFloaterProperties ///---------------------------------------------------------------------------- // Default constructor LLFloaterProperties::LLFloaterProperties(const LLSD& key) : LLFloater(key), mDirty(true) // Avatar names often not showing on first open ,mCreatorNameCbConnection(), mOwnerNameCbConnection(), mGroupOwnerNameCbConnection() // { if (key.has("item_id")) { mItemID = key["item_id"].asUUID(); if (key.has("object_id")) mObjectID = key["object_id"].asUUID(); } mPropertiesObserver = new LLPropertiesObserver(this); } // Destroys the object LLFloaterProperties::~LLFloaterProperties() { delete mPropertiesObserver; mPropertiesObserver = NULL; // Avatar names often not showing on first open if (mCreatorNameCbConnection.connected()) { mCreatorNameCbConnection.disconnect(); } if (mOwnerNameCbConnection.connected()) { mOwnerNameCbConnection.disconnect(); } if (mGroupOwnerNameCbConnection.connected()) { mGroupOwnerNameCbConnection.disconnect(); } // } // virtual bool LLFloaterProperties::postBuild() { // build the UI // item name & description getChild("LabelItemName")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); getChild("LabelItemName")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitName,this)); getChild("LabelItemDesc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); getChild("LabelItemDesc")->setCommitCallback(boost::bind(&LLFloaterProperties:: onCommitDescription, this)); // Creator information getChild("BtnCreator")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickCreator,this)); // owner information getChild("BtnOwner")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickOwner,this)); // acquired date // owner permissions // Permissions debug text // group permissions getChild("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); // everyone permissions getChild("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); // next owner permissions getChild("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); getChild("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); getChild("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); // OpenSim export permissions getChild("CheckOwnerExport")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); getChild("CheckOwnerExport")->setVisible(!LLGridManager::getInstance()->isInSecondLife()); // // Mark for sale or not, and sale info getChild("CheckPurchase")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); getChild("ComboBoxSaleType")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleType, this)); // "Price" label for edit getChild("Edit Cost")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); // The UI has been built, now fill in all the values refresh(); return true; } // virtual void LLFloaterProperties::onOpen(const LLSD& key) { refresh(); } void LLFloaterProperties::refresh() { LLInventoryItem* item = findItem(); if(item) { refreshFromItem(item); } else { //RN: it is possible that the container object is in the middle of an inventory refresh // causing findItem() to fail, so just temporarily disable everything mDirty = true; const char* enableNames[]={ "LabelItemName", "LabelItemDesc", "LabelCreatorName", "BtnCreator", "LabelOwnerName", "BtnOwner", "CheckOwnerModify", "CheckOwnerCopy", "CheckOwnerTransfer", "CheckShareWithGroup", "CheckEveryoneCopy", "CheckNextOwnerModify", "CheckNextOwnerCopy", "CheckNextOwnerTransfer", "CheckOwnerExport", // OpenSim export permissions "CheckPurchase", "ComboBoxSaleType", "Edit Cost" }; for(size_t t=0; tsetEnabled(false); } const char* hideNames[]={ "BaseMaskDebug", "OwnerMaskDebug", "GroupMaskDebug", "EveryoneMaskDebug", "NextMaskDebug" }; for(size_t t=0; tsetVisible(false); } } } void LLFloaterProperties::draw() { if (mDirty) { // RN: clear dirty first because refresh can set dirty to true mDirty = false; refresh(); } LLFloater::draw(); } void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) { //////////////////////// // PERMISSIONS LOOKUP // //////////////////////// // do not enable the UI for incomplete items. LLViewerInventoryItem* i = (LLViewerInventoryItem*)item; bool is_complete = i->isFinished(); const bool cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(i->getInventoryType()); const bool is_calling_card = (i->getInventoryType() == LLInventoryType::IT_CALLINGCARD); const bool is_settings = (item->getInventoryType() == LLInventoryType::IT_SETTINGS); const LLPermissions& perm = item->getPermissions(); const bool can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm, GP_OBJECT_MANIPULATE); const bool can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm, GP_OBJECT_SET_SALE) && !cannot_restrict_permissions; const bool is_link = i->getIsLinkType(); // You need permission to modify the object to modify an inventory // item in it. LLViewerObject* object = NULL; if(!mObjectID.isNull()) object = gObjectList.findObject(mObjectID); bool is_obj_modify = true; if(object) { is_obj_modify = object->permOwnerModify(); } // Experience info if(item->getInventoryType() == LLInventoryType::IT_LSL) { getChildView("LabelItemExperienceTitle")->setVisible(true); LLTextBox* tb = getChild("LabelItemExperience"); tb->setText(getString("loading_experience")); tb->setVisible(true); LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), boost::bind(&LLFloaterProperties::setAssociatedExperience, getDerivedHandle(), _1)); } // ////////////////////// // ITEM NAME & DESC // ////////////////////// bool is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE) && is_obj_modify && is_complete; getChildView("LabelItemNameTitle")->setEnabled(true); getChildView("LabelItemName")->setEnabled(is_modifiable && !is_calling_card); // for now, don't allow rename of calling cards getChild("LabelItemName")->setValue(item->getName()); getChildView("LabelItemDescTitle")->setEnabled(true); getChildView("LabelItemDesc")->setEnabled(is_modifiable); getChildView("IconLocked")->setVisible(!is_modifiable); getChild("LabelItemDesc")->setValue(item->getDescription()); ////////////////// // CREATOR NAME // ////////////////// if(!gCacheName) return; if(!gAgent.getRegion()) return; if (item->getCreatorUUID().notNull()) { // Avatar names often not showing on first open //LLAvatarName av_name; //LLAvatarNameCache::get(item->getCreatorUUID(), &av_name); //getChildView("BtnCreator")->setEnabled(true); // getChildView("LabelCreatorTitle")->setEnabled(true); getChildView("LabelCreatorName")->setEnabled(true); // Avatar names often not showing on first open //getChild("LabelCreatorName")->setValue(av_name.getUserName()); getChildView("BtnCreator")->setEnabled(false); getChild("LabelCreatorName")->setValue(LLTrans::getString("AvatarNameWaiting")); mCreatorNameCbConnection = LLAvatarNameCache::get(item->getCreatorUUID(), boost::bind(&LLFloaterProperties::onCreatorNameCallback, this, _1, _2, perm)); // } else { getChildView("BtnCreator")->setEnabled(false); getChildView("LabelCreatorTitle")->setEnabled(false); getChildView("LabelCreatorName")->setEnabled(false); getChild("LabelCreatorName")->setValue(getString("unknown")); } //////////////// // OWNER NAME // //////////////// if(perm.isOwned()) { // Avatar names often not showing on first open //std::string name; getChildView("BtnOwner")->setEnabled(false); getChild("LabelOwnerName")->setValue(LLTrans::getString("AvatarNameWaiting")); // if (perm.isGroupOwned()) { // Avatar names often not showing on first open //gCacheName->getGroupName(perm.getGroup(), name); mGroupOwnerNameCbConnection = gCacheName->getGroup(perm.getGroup(), boost::bind(&LLFloaterProperties::onGroupOwnerNameCallback, this, _2)); // } else { // Avatar names often not showing on first open //LLAvatarName av_name; //LLAvatarNameCache::get(perm.getOwner(), &av_name); //name = av_name.getUserName(); mOwnerNameCbConnection = LLAvatarNameCache::get(perm.getOwner(), boost::bind(&LLFloaterProperties::onOwnerNameCallback, this, _1, _2)); // } //getChildView("BtnOwner")->setEnabled(true); // Avatar names often not showing on first open getChildView("LabelOwnerTitle")->setEnabled(true); getChildView("LabelOwnerName")->setEnabled(true); //getChild("LabelOwnerName")->setValue(name); // Avatar names often not showing on first open } else { getChildView("BtnOwner")->setEnabled(false); getChildView("LabelOwnerTitle")->setEnabled(false); getChildView("LabelOwnerName")->setEnabled(false); getChild("LabelOwnerName")->setValue(getString("public")); } ////////////////// // ACQUIRE DATE // ////////////////// time_t time_utc = item->getCreationDate(); if (0 == time_utc) { getChild("LabelAcquiredDate")->setValue(getString("unknown")); } else { std::string timeStr = getString("acquiredDate"); LLSD substitution; substitution["datetime"] = (S32) time_utc; LLStringUtil::format (timeStr, substitution); getChild("LabelAcquiredDate")->setValue(timeStr); } /////////////////////// // OWNER PERMISSIONS // /////////////////////// if(can_agent_manipulate) { getChild("OwnerLabel")->setValue(getString("you_can")); } else { getChild("OwnerLabel")->setValue(getString("owner_can")); } U32 base_mask = perm.getMaskBase(); U32 owner_mask = perm.getMaskOwner(); U32 group_mask = perm.getMaskGroup(); U32 everyone_mask = perm.getMaskEveryone(); U32 next_owner_mask = perm.getMaskNextOwner(); getChildView("OwnerLabel")->setEnabled(true); getChildView("CheckOwnerModify")->setEnabled(false); getChild("CheckOwnerModify")->setValue(LLSD((bool)(owner_mask & PERM_MODIFY))); getChildView("CheckOwnerCopy")->setEnabled(false); getChild("CheckOwnerCopy")->setValue(LLSD((bool)(owner_mask & PERM_COPY))); getChildView("CheckOwnerTransfer")->setEnabled(false); getChild("CheckOwnerTransfer")->setValue(LLSD((bool)(owner_mask & PERM_TRANSFER))); // OpenSim export permissions getChildView("CheckOwnerExport")->setEnabled(false); getChild("CheckOwnerExport")->setValue(LLSD((bool)(owner_mask & PERM_EXPORT))); // /////////////////////// // DEBUG PERMISSIONS // /////////////////////// if( gSavedSettings.getBOOL("DebugPermissions") ) { bool slam_perm = false; bool overwrite_group = false; bool overwrite_everyone = false; if (item->getType() == LLAssetType::AT_OBJECT) { U32 flags = item->getFlags(); slam_perm = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM; overwrite_everyone = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE; overwrite_group = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP; } std::string perm_string; // remove misleading X for export when not in OpenSim bool isOpenSim {false}; #ifdef OPENSIM if( LLGridManager::instance().isInOpenSim() ) { isOpenSim = true; } #endif // perm_string = "B: "; perm_string += mask_to_string(base_mask, isOpenSim); // remove misleading X for export when not in OpenSim getChild("BaseMaskDebug")->setValue(perm_string); getChildView("BaseMaskDebug")->setVisible(true); perm_string = "O: "; perm_string += mask_to_string(owner_mask, isOpenSim); // remove misleading X for export when not in OpenSim getChild("OwnerMaskDebug")->setValue(perm_string); getChildView("OwnerMaskDebug")->setVisible(true); perm_string = "G"; perm_string += overwrite_group ? "*: " : ": "; perm_string += mask_to_string(group_mask, isOpenSim); // remove misleading X for export when not in OpenSim getChild("GroupMaskDebug")->setValue(perm_string); getChildView("GroupMaskDebug")->setVisible(true); perm_string = "E"; perm_string += overwrite_everyone ? "*: " : ": "; perm_string += mask_to_string(everyone_mask, isOpenSim); // remove misleading X for export when not in OpenSim getChild("EveryoneMaskDebug")->setValue(perm_string); getChildView("EveryoneMaskDebug")->setVisible(true); perm_string = "N"; perm_string += slam_perm ? "*: " : ": "; perm_string += mask_to_string(next_owner_mask, isOpenSim); // remove misleading X for export when not in OpenSim getChild("NextMaskDebug")->setValue(perm_string); getChildView("NextMaskDebug")->setVisible(true); } else { getChildView("BaseMaskDebug")->setVisible(false); getChildView("OwnerMaskDebug")->setVisible(false); getChildView("GroupMaskDebug")->setVisible(false); getChildView("EveryoneMaskDebug")->setVisible(false); getChildView("NextMaskDebug")->setVisible(false); } ///////////// // SHARING // ///////////// // Check for ability to change values. if (is_link || cannot_restrict_permissions) { getChildView("CheckShareWithGroup")->setEnabled(false); getChildView("CheckEveryoneCopy")->setEnabled(false); } else if (is_obj_modify && can_agent_manipulate) { getChildView("CheckShareWithGroup")->setEnabled(true); getChildView("CheckEveryoneCopy")->setEnabled((owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER)); } else { getChildView("CheckShareWithGroup")->setEnabled(false); getChildView("CheckEveryoneCopy")->setEnabled(false); } getChildView("CheckOwnerExport")->setEnabled(gAgentID == item->getCreatorUUID()); // OpenSim export permissions // Set values. bool is_group_copy = (group_mask & PERM_COPY) ? true : false; bool is_group_modify = (group_mask & PERM_MODIFY) ? true : false; bool is_group_move = (group_mask & PERM_MOVE) ? true : false; if (is_group_copy && is_group_modify && is_group_move) { getChild("CheckShareWithGroup")->setValue(LLSD(true)); LLCheckBoxCtrl* ctl = getChild("CheckShareWithGroup"); if(ctl) { ctl->setTentative(false); } } else if (!is_group_copy && !is_group_modify && !is_group_move) { getChild("CheckShareWithGroup")->setValue(LLSD(false)); LLCheckBoxCtrl* ctl = getChild("CheckShareWithGroup"); if(ctl) { ctl->setTentative(false); } } else { LLCheckBoxCtrl* ctl = getChild("CheckShareWithGroup"); if(ctl) { ctl->setTentative(true); ctl->set(true); } } getChild("CheckEveryoneCopy")->setValue(LLSD((bool)(everyone_mask & PERM_COPY))); /////////////// // SALE INFO // /////////////// const LLSaleInfo& sale_info = item->getSaleInfo(); bool is_for_sale = sale_info.isForSale(); LLComboBox* combo_sale_type = getChild("ComboBoxSaleType"); LLUICtrl* edit_cost = getChild("Edit Cost"); // Check for ability to change values. if (is_obj_modify && can_agent_sell && gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE)) { getChildView("CheckPurchase")->setEnabled(is_complete); getChildView("NextOwnerLabel")->setEnabled(true); getChildView("CheckNextOwnerModify")->setEnabled((base_mask & PERM_MODIFY) && !cannot_restrict_permissions); getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions && !is_settings); getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions); combo_sale_type->setEnabled(is_complete && is_for_sale); edit_cost->setEnabled(is_complete && is_for_sale); } else { getChildView("CheckPurchase")->setEnabled(false); getChildView("NextOwnerLabel")->setEnabled(false); getChildView("CheckNextOwnerModify")->setEnabled(false); getChildView("CheckNextOwnerCopy")->setEnabled(false); getChildView("CheckNextOwnerTransfer")->setEnabled(false); combo_sale_type->setEnabled(false); edit_cost->setEnabled(false); } // Hide any properties that are not relevant to settings if (is_settings) { getChild("GroupLabel")->setEnabled(false); getChild("GroupLabel")->setVisible(false); getChild("CheckShareWithGroup")->setEnabled(false); getChild("CheckShareWithGroup")->setVisible(false); getChild("AnyoneLabel")->setEnabled(false); getChild("AnyoneLabel")->setVisible(false); getChild("CheckEveryoneCopy")->setEnabled(false); getChild("CheckEveryoneCopy")->setVisible(false); getChild("CheckPurchase")->setEnabled(false); getChild("CheckPurchase")->setVisible(false); getChild("ComboBoxSaleType")->setEnabled(false); getChild("ComboBoxSaleType")->setVisible(false); getChild("Edit Cost")->setEnabled(false); getChild("Edit Cost")->setVisible(false); getChild("CurrencySymbol")->setEnabled(false); getChild("CurrencySymbol")->setVisible(false); } // Set values. getChild("CheckPurchase")->setValue(is_for_sale); getChild("CheckNextOwnerModify")->setValue(LLSD(bool(next_owner_mask & PERM_MODIFY))); getChild("CheckNextOwnerCopy")->setValue(LLSD(bool(next_owner_mask & PERM_COPY))); getChild("CheckNextOwnerTransfer")->setValue(LLSD(bool(next_owner_mask & PERM_TRANSFER))); if (is_for_sale) { S32 numerical_price; numerical_price = sale_info.getSalePrice(); edit_cost->setValue(llformat("%d",numerical_price)); combo_sale_type->setValue(sale_info.getSaleType()); } else { edit_cost->setValue(llformat("%d",0)); combo_sale_type->setValue(LLSaleInfo::FS_COPY); } } // Experience info void LLFloaterProperties::setAssociatedExperience( LLHandle hInfo, const LLSD& experience ) { LLFloaterProperties* info = hInfo.get(); if(info) { LLUUID id; if(experience.has(LLExperienceCache::EXPERIENCE_ID)) { id=experience[LLExperienceCache::EXPERIENCE_ID].asUUID(); } if(id.notNull()) { info->getChild("LabelItemExperience")->setText(LLSLURL("experience", id, "profile").getSLURLString()); } else { info->getChild("LabelItemExperience")->setText(LLTrans::getString("ExperienceNameNull")); } } } // void LLFloaterProperties::onClickCreator() { LLInventoryItem* item = findItem(); if(!item) return; if(!item->getCreatorUUID().isNull()) { // [RLVa:KB] - Checked: RLVa-1.2.1 const LLUUID& idCreator = item->getCreatorUUID(); if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, idCreator)) ) { const LLPermissions& perm = item->getPermissions(); if ( ((perm.isOwned()) && (!perm.isGroupOwned()) && (perm.getOwner() == idCreator) ) || (RlvUtil::isNearbyAgent(idCreator)) ) { return; } } // [/RLVa:KB] LLAvatarActions::showProfile(item->getCreatorUUID()); } } // static void LLFloaterProperties::onClickOwner() { LLInventoryItem* item = findItem(); if(!item) return; if(item->getPermissions().isGroupOwned()) { LLGroupActions::show(item->getPermissions().getGroup()); } else { // [RLVa:KB] - Checked: RLVa-1.0.0 if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, item->getPermissions().getOwner())) ) return; // [/RLVa:KB] LLAvatarActions::showProfile(item->getPermissions().getOwner()); } } // static void LLFloaterProperties::onCommitName() { //LL_INFOS() << "LLFloaterProperties::onCommitName()" << LL_ENDL; LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); if(!item) { return; } LLLineEditor* labelItemName = getChild("LabelItemName"); if(labelItemName&& (item->getName() != labelItemName->getText()) && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) ) { LLPointer new_item = new LLViewerInventoryItem(item); new_item->rename(labelItemName->getText()); if(mObjectID.isNull()) { new_item->updateServer(false); gInventory.updateItem(new_item); gInventory.notifyObservers(); } else { LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { object->updateInventory( new_item, TASK_INVENTORY_ITEM_KEY, false); } } } } void LLFloaterProperties::onCommitDescription() { //LL_INFOS() << "LLFloaterProperties::onCommitDescription()" << LL_ENDL; LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); if(!item) return; LLLineEditor* labelItemDesc = getChild("LabelItemDesc"); if(!labelItemDesc) { return; } if((item->getDescription() != labelItemDesc->getText()) && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))) { LLPointer new_item = new LLViewerInventoryItem(item); new_item->setDescription(labelItemDesc->getText()); if(mObjectID.isNull()) { new_item->updateServer(false); gInventory.updateItem(new_item); gInventory.notifyObservers(); } else { LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { object->updateInventory( new_item, TASK_INVENTORY_ITEM_KEY, false); } } } } // static void LLFloaterProperties::onCommitPermissions() { //LL_INFOS() << "LLFloaterProperties::onCommitPermissions()" << LL_ENDL; LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); if(!item) return; LLPermissions perm(item->getPermissions()); LLCheckBoxCtrl* CheckShareWithGroup = getChild("CheckShareWithGroup"); if(CheckShareWithGroup) { perm.setGroupBits(gAgent.getID(), gAgent.getGroupID(), CheckShareWithGroup->get(), PERM_MODIFY | PERM_MOVE | PERM_COPY); } LLCheckBoxCtrl* CheckEveryoneCopy = getChild("CheckEveryoneCopy"); if(CheckEveryoneCopy) { perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(), CheckEveryoneCopy->get(), PERM_COPY); } LLCheckBoxCtrl* CheckNextOwnerModify = getChild("CheckNextOwnerModify"); if(CheckNextOwnerModify) { perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), CheckNextOwnerModify->get(), PERM_MODIFY); } LLCheckBoxCtrl* CheckNextOwnerCopy = getChild("CheckNextOwnerCopy"); if(CheckNextOwnerCopy) { perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), CheckNextOwnerCopy->get(), PERM_COPY); } LLCheckBoxCtrl* CheckNextOwnerTransfer = getChild("CheckNextOwnerTransfer"); if(CheckNextOwnerTransfer) { perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), CheckNextOwnerTransfer->get(), PERM_TRANSFER); } // OpenSim export permissions LLCheckBoxCtrl* CheckOwnerExport = getChild("CheckOwnerExport"); if (CheckOwnerExport) { perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), CheckOwnerExport->get(), PERM_EXPORT); } if(perm != item->getPermissions() && item->isFinished()) { LLPointer new_item = new LLViewerInventoryItem(item); new_item->setPermissions(perm); U32 flags = new_item->getFlags(); // If next owner permissions have changed (and this is an object) // then set the slam permissions flag so that they are applied on rez. if((perm.getMaskNextOwner()!=item->getPermissions().getMaskNextOwner()) && (item->getType() == LLAssetType::AT_OBJECT)) { flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM; } // If everyone permissions have changed (and this is an object) // then set the overwrite everyone permissions flag so they // are applied on rez. if ((perm.getMaskEveryone()!=item->getPermissions().getMaskEveryone()) && (item->getType() == LLAssetType::AT_OBJECT)) { flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE; } // If group permissions have changed (and this is an object) // then set the overwrite group permissions flag so they // are applied on rez. if ((perm.getMaskGroup()!=item->getPermissions().getMaskGroup()) && (item->getType() == LLAssetType::AT_OBJECT)) { flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP; } new_item->setFlags(flags); if(mObjectID.isNull()) { new_item->updateServer(false); gInventory.updateItem(new_item); gInventory.notifyObservers(); } else { LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { object->updateInventory( new_item, TASK_INVENTORY_ITEM_KEY, false); } } } else { // need to make sure we don't just follow the click refresh(); } } // static void LLFloaterProperties::onCommitSaleInfo() { //LL_INFOS() << "LLFloaterProperties::onCommitSaleInfo()" << LL_ENDL; updateSaleInfo(); } // static void LLFloaterProperties::onCommitSaleType() { //LL_INFOS() << "LLFloaterProperties::onCommitSaleType()" << LL_ENDL; updateSaleInfo(); } void LLFloaterProperties::updateSaleInfo() { LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); if(!item) return; LLSaleInfo sale_info(item->getSaleInfo()); if(!gAgent.allowOperation(PERM_TRANSFER, item->getPermissions(), GP_OBJECT_SET_SALE)) { getChild("CheckPurchase")->setValue(LLSD(false)); } if((bool)getChild("CheckPurchase")->getValue()) { // turn on sale info LLSaleInfo::EForSale sale_type = LLSaleInfo::FS_COPY; LLComboBox* combo_sale_type = getChild("ComboBoxSaleType"); if (combo_sale_type) { sale_type = static_cast(combo_sale_type->getValue().asInteger()); } if (sale_type == LLSaleInfo::FS_COPY && !gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_SET_SALE)) { sale_type = LLSaleInfo::FS_ORIGINAL; } S32 price = -1; price = getChild("Edit Cost")->getValue().asInteger();; // Invalid data - turn off the sale if (price < 0) { sale_type = LLSaleInfo::FS_NOT; price = 0; } sale_info.setSaleType(sale_type); sale_info.setSalePrice(price); } else { sale_info.setSaleType(LLSaleInfo::FS_NOT); } if(sale_info != item->getSaleInfo() && item->isFinished()) { LLPointer new_item = new LLViewerInventoryItem(item); // Force an update on the sale price at rez if (item->getType() == LLAssetType::AT_OBJECT) { U32 flags = new_item->getFlags(); flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_SALE; new_item->setFlags(flags); } new_item->setSaleInfo(sale_info); if(mObjectID.isNull()) { // This is in the agent's inventory. new_item->updateServer(false); gInventory.updateItem(new_item); gInventory.notifyObservers(); } else { // This is in an object's contents. LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { object->updateInventory( new_item, TASK_INVENTORY_ITEM_KEY, false); } } } else { // need to make sure we don't just follow the click refresh(); } } LLInventoryItem* LLFloaterProperties::findItem() const { LLInventoryItem* item = NULL; if(mObjectID.isNull()) { // it is in agent inventory item = gInventory.getItem(mItemID); } else { LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { item = (LLInventoryItem*)object->getInventoryObject(mItemID); } } return item; } //static void LLFloaterProperties::dirtyAll() { LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("properties"); for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) { LLFloaterProperties* floater = dynamic_cast(*iter); llassert(floater); // else cast failed - wrong type D: if (floater) { floater->dirty(); } } } // Avatar names often not showing on first open void LLFloaterProperties::onCreatorNameCallback(const LLUUID& av_id, const LLAvatarName& av_name, const LLPermissions& perm) { bool enabled = true; std::string name = av_name.getUserName(); // If the object creator matches the object owner we need to anonymize the creator field as well if ( (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, av_id)) && ( ((perm.isOwned()) && (!perm.isGroupOwned()) && (perm.getOwner() == av_id) ) || (RlvUtil::isNearbyAgent(av_id)) ) ) { enabled = false; name = RlvStrings::getAnonym(av_name); } getChild("LabelCreatorName")->setValue(name); childSetEnabled("BtnCreator", enabled); } void LLFloaterProperties::onOwnerNameCallback(const LLUUID& av_id, const LLAvatarName& av_name) { bool fRlvCanShowOwner = true; std::string name = av_name.getUserName(); if (RlvActions::isRlvEnabled()) { fRlvCanShowOwner = RlvActions::canShowName(RlvActions::SNC_DEFAULT, av_id); if (!fRlvCanShowOwner) { name = RlvStrings::getAnonym(av_name); } } getChild("LabelOwnerName")->setValue(name); getChildView("BtnOwner")->setEnabled(fRlvCanShowOwner); } void LLFloaterProperties::onGroupOwnerNameCallback(const std::string& name) { getChild("LabelOwnerName")->setValue(name); getChildView("BtnOwner")->setEnabled(true); } // ///---------------------------------------------------------------------------- /// LLMultiProperties ///---------------------------------------------------------------------------- LLMultiProperties::LLMultiProperties() : LLMultiFloater(LLSD()) { // start with a small rect in the top-left corner ; will get resized LLRect rect; rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 350, 350); setRect(rect); LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup("properties"); if (last_floater) { stackWith(*last_floater); } setTitle(LLTrans::getString("MultiPropertiesTitle")); buildTabContainer(); // Center multifloater on screen center(); } ///---------------------------------------------------------------------------- /// Local function definitions ///----------------------------------------------------------------------------