1277 lines
43 KiB
C++
1277 lines
43 KiB
C++
/**
|
|
* @file llsidepaneliteminfo.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 "llsidepaneliteminfo.h"
|
|
|
|
#include "roles_constants.h"
|
|
|
|
#include "llagent.h"
|
|
#include "llavataractions.h"
|
|
#include "llavatarnamecache.h"
|
|
#include "llbutton.h"
|
|
#include "llcallbacklist.h"
|
|
#include "llcombobox.h"
|
|
#include "llfloater.h"
|
|
#include "llfloaterreg.h"
|
|
#include "llgroupactions.h"
|
|
#include "llgroupmgr.h"
|
|
#include "lliconctrl.h"
|
|
#include "llinventorydefines.h"
|
|
#include "llinventoryicon.h"
|
|
#include "llinventorymodel.h"
|
|
#include "llinventoryobserver.h"
|
|
#include "lllineeditor.h"
|
|
#include "llradiogroup.h"
|
|
#include "llslurl.h"
|
|
#include "lltexteditor.h"
|
|
#include "llviewercontrol.h"
|
|
#include "llviewerinventory.h"
|
|
#include "llviewerobjectlist.h"
|
|
#include "llexperiencecache.h"
|
|
#include "lltrans.h"
|
|
#include "llviewerregion.h"
|
|
#include "llviewernetwork.h" // <FS:Beq/> for gridmanager
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
#include "rlvactions.h"
|
|
#include "rlvcommon.h"
|
|
// [/RLVa:KB]
|
|
|
|
class PropertiesChangedCallback : public LLInventoryCallback
|
|
{
|
|
public:
|
|
PropertiesChangedCallback(LLHandle<LLPanel> sidepanel_handle, LLUUID &item_id, S32 id)
|
|
: mHandle(sidepanel_handle), mItemId(item_id), mId(id)
|
|
{}
|
|
|
|
void fire(const LLUUID &inv_item)
|
|
{
|
|
// inv_item can be null for some reason
|
|
LLSidepanelItemInfo* sidepanel = dynamic_cast<LLSidepanelItemInfo*>(mHandle.get());
|
|
if (sidepanel)
|
|
{
|
|
// sidepanel waits only for most recent update
|
|
sidepanel->onUpdateCallback(mItemId, mId);
|
|
}
|
|
}
|
|
private:
|
|
LLHandle<LLPanel> mHandle;
|
|
LLUUID mItemId;
|
|
S32 mId;
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Class LLObjectInventoryObserver
|
|
//
|
|
// Helper class to watch for changes in an object inventory.
|
|
// Used to update item properties in LLSidepanelItemInfo.
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
class LLObjectInventoryObserver : public LLVOInventoryListener
|
|
{
|
|
public:
|
|
LLObjectInventoryObserver(LLSidepanelItemInfo* floater, LLViewerObject* object)
|
|
: mFloater(floater)
|
|
{
|
|
registerVOInventoryListener(object, NULL);
|
|
}
|
|
virtual ~LLObjectInventoryObserver()
|
|
{
|
|
removeVOInventoryListener();
|
|
}
|
|
/*virtual*/ void inventoryChanged(LLViewerObject* object,
|
|
LLInventoryObject::object_list_t* inventory,
|
|
S32 serial_num,
|
|
void* user_data);
|
|
private:
|
|
LLSidepanelItemInfo* mFloater; // Not a handle because LLSidepanelItemInfo is managing LLObjectInventoryObserver
|
|
};
|
|
|
|
/*virtual*/
|
|
void LLObjectInventoryObserver::inventoryChanged(LLViewerObject* object,
|
|
LLInventoryObject::object_list_t* inventory,
|
|
S32 serial_num,
|
|
void* user_data)
|
|
{
|
|
mFloater->dirty();
|
|
}
|
|
|
|
///----------------------------------------------------------------------------
|
|
/// Class LLSidepanelItemInfo
|
|
///----------------------------------------------------------------------------
|
|
|
|
static LLPanelInjector<LLSidepanelItemInfo> t_item_info("sidepanel_item_info");
|
|
|
|
// Default constructor
|
|
LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p)
|
|
: LLPanel(p)
|
|
, mItemID(LLUUID::null)
|
|
, mObjectInventoryObserver(NULL)
|
|
, mUpdatePendingId(-1)
|
|
, mIsDirty(false) /*Not ready*/
|
|
, mParentFloater(NULL)
|
|
{
|
|
gInventory.addObserver(this);
|
|
gIdleCallbacks.addFunction(&LLSidepanelItemInfo::onIdle, (void*)this);
|
|
}
|
|
|
|
// Destroys the object
|
|
LLSidepanelItemInfo::~LLSidepanelItemInfo()
|
|
{
|
|
gInventory.removeObserver(this);
|
|
gIdleCallbacks.deleteFunction(&LLSidepanelItemInfo::onIdle, (void*)this);
|
|
|
|
stopObjectInventoryObserver();
|
|
|
|
if (mOwnerCacheConnection.connected())
|
|
{
|
|
mOwnerCacheConnection.disconnect();
|
|
}
|
|
if (mCreatorCacheConnection.connected())
|
|
{
|
|
mCreatorCacheConnection.disconnect();
|
|
}
|
|
}
|
|
|
|
// virtual
|
|
bool LLSidepanelItemInfo::postBuild()
|
|
{
|
|
mChangeThumbnailBtn = getChild<LLUICtrl>("change_thumbnail_btn");
|
|
mItemTypeIcon = getChild<LLIconCtrl>("item_type_icon");
|
|
mLabelOwnerName = getChild<LLTextBox>("LabelOwnerName");
|
|
mLabelCreatorName = getChild<LLTextBox>("LabelCreatorName");
|
|
|
|
getChild<LLLineEditor>("LabelItemName")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
|
|
getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitName,this));
|
|
getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLSidepanelItemInfo:: onCommitDescription, this));
|
|
// Thumnail edition
|
|
mChangeThumbnailBtn->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onEditThumbnail, this));
|
|
// acquired date
|
|
// owner permissions
|
|
// Permissions debug text
|
|
// group permissions
|
|
getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
|
|
// everyone permissions
|
|
getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
|
|
// next owner permissions
|
|
getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
|
|
getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
|
|
getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
|
|
// Mark for sale or not, and sale info
|
|
getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
|
|
// Change sale type, and sale info
|
|
getChild<LLUICtrl>("ComboBoxSaleType")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
|
|
// "Price" label for edit
|
|
getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
|
|
refresh();
|
|
return true;
|
|
}
|
|
|
|
void LLSidepanelItemInfo::setObjectID(const LLUUID& object_id)
|
|
{
|
|
mObjectID = object_id;
|
|
|
|
// Start monitoring changes in the object inventory to update
|
|
// selected inventory item properties in Item Profile panel. See STORM-148.
|
|
startObjectInventoryObserver();
|
|
mUpdatePendingId = -1;
|
|
}
|
|
|
|
void LLSidepanelItemInfo::setItemID(const LLUUID& item_id)
|
|
{
|
|
if (mItemID != item_id)
|
|
{
|
|
mItemID = item_id;
|
|
mUpdatePendingId = -1;
|
|
}
|
|
dirty();
|
|
}
|
|
|
|
void LLSidepanelItemInfo::setParentFloater(LLFloater* parent)
|
|
{
|
|
mParentFloater = parent;
|
|
}
|
|
|
|
const LLUUID& LLSidepanelItemInfo::getObjectID() const
|
|
{
|
|
return mObjectID;
|
|
}
|
|
|
|
const LLUUID& LLSidepanelItemInfo::getItemID() const
|
|
{
|
|
return mItemID;
|
|
}
|
|
|
|
void LLSidepanelItemInfo::onUpdateCallback(const LLUUID& item_id, S32 received_update_id)
|
|
{
|
|
if (mItemID == item_id && mUpdatePendingId == received_update_id)
|
|
{
|
|
mUpdatePendingId = -1;
|
|
refresh();
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::reset()
|
|
{
|
|
mObjectID = LLUUID::null;
|
|
mItemID = LLUUID::null;
|
|
|
|
stopObjectInventoryObserver();
|
|
dirty();
|
|
}
|
|
|
|
void LLSidepanelItemInfo::refresh()
|
|
{
|
|
LLViewerInventoryItem* item = findItem();
|
|
if(item)
|
|
{
|
|
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
|
bool in_trash = (item->getUUID() == trash_id) || gInventory.isObjectDescendentOf(item->getUUID(), trash_id);
|
|
if (in_trash && mParentFloater)
|
|
{
|
|
// Close properties when moving to trash
|
|
// Aren't supposed to view properties from trash
|
|
mParentFloater->closeFloater();
|
|
}
|
|
else
|
|
{
|
|
refreshFromItem(item);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (mObjectID.notNull())
|
|
{
|
|
LLViewerObject* object = gObjectList.findObject(mObjectID);
|
|
if (object)
|
|
{
|
|
// Object exists, but object's content is not nessesary
|
|
// loaded, so assume item exists as well
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (mParentFloater)
|
|
{
|
|
// if we failed to get item, it likely no longer exists
|
|
mParentFloater->closeFloater();
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
|
|
{
|
|
////////////////////////
|
|
// PERMISSIONS LOOKUP //
|
|
////////////////////////
|
|
|
|
llassert(item);
|
|
if (!item) return;
|
|
|
|
if (mUpdatePendingId != -1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// do not enable the UI for incomplete items.
|
|
bool is_complete = item->isFinished();
|
|
const bool cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(item->getInventoryType());
|
|
const bool is_calling_card = (item->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 = item->getIsLinkType();
|
|
|
|
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
|
bool not_in_trash = (item->getUUID() != trash_id) && !gInventory.isObjectDescendentOf(item->getUUID(), trash_id);
|
|
|
|
// 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();
|
|
}
|
|
|
|
if(item->getInventoryType() == LLInventoryType::IT_LSL)
|
|
{
|
|
getChildView("LabelItemExperienceTitle")->setVisible(true);
|
|
LLTextBox* tb = getChild<LLTextBox>("LabelItemExperience");
|
|
tb->setText(getString("loading_experience"));
|
|
tb->setVisible(true);
|
|
std::string url = std::string();
|
|
if(object && object->getRegion())
|
|
{
|
|
url = object->getRegion()->getCapability("GetMetadata");
|
|
}
|
|
LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), url,
|
|
boost::bind(&LLSidepanelItemInfo::setAssociatedExperience, getDerivedHandle<LLSidepanelItemInfo>(), _1));
|
|
}
|
|
|
|
//////////////////////
|
|
// ITEM NAME & DESC //
|
|
//////////////////////
|
|
bool is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm,
|
|
GP_OBJECT_MANIPULATE)
|
|
&& is_obj_modify && is_complete && not_in_trash;
|
|
|
|
//getChildView("LabelItemNameTitle")->setEnabled(true); // <FS:Ansariel> Doesn't exist as of 04-10-2023
|
|
getChildView("LabelItemName")->setEnabled(is_modifiable && !is_calling_card); // for now, don't allow rename of calling cards
|
|
getChild<LLUICtrl>("LabelItemName")->setValue(item->getName());
|
|
getChildView("LabelItemDescTitle")->setEnabled(true);
|
|
getChildView("LabelItemDesc")->setEnabled(is_modifiable);
|
|
getChild<LLUICtrl>("LabelItemDesc")->setValue(item->getDescription());
|
|
getChild<LLUICtrl>("item_thumbnail")->setValue(item->getThumbnailUUID());
|
|
|
|
LLUIImagePtr icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), false);
|
|
mItemTypeIcon->setImage(icon_img);
|
|
|
|
// Style for creator and owner links
|
|
LLStyle::Params style_params;
|
|
LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
|
|
style_params.color = link_color;
|
|
style_params.readonly_color = link_color;
|
|
style_params.is_link = true; // link will be added later
|
|
const LLFontGL* fontp = mLabelCreatorName->getFont();
|
|
style_params.font.name = LLFontGL::nameFromFont(fontp);
|
|
style_params.font.size = LLFontGL::sizeFromFont(fontp);
|
|
style_params.font.style = "UNDERLINE";
|
|
|
|
//////////////////
|
|
// CREATOR NAME //
|
|
//////////////////
|
|
if(!gCacheName) return;
|
|
if(!gAgent.getRegion()) return;
|
|
|
|
if (item->getCreatorUUID().notNull())
|
|
{
|
|
LLUUID creator_id = item->getCreatorUUID();
|
|
// std::string slurl =
|
|
// LLSLURL("agent", creator_id, "inspect").getSLURLString();
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
// If the object creator matches the object owner we need to anonymize the creator field as well
|
|
bool fRlvCanShowCreator = true;
|
|
if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, creator_id)) &&
|
|
( ((perm.isOwned()) && (!perm.isGroupOwned()) && (perm.getOwner() == creator_id) ) || (RlvUtil::isNearbyAgent(item->getCreatorUUID())) ) )
|
|
{
|
|
fRlvCanShowCreator = false;
|
|
}
|
|
std::string slurl = LLSLURL("agent", creator_id, (fRlvCanShowCreator) ? "inspect" : "rlvanonym").getSLURLString();
|
|
// [/RLVa:KB]
|
|
|
|
style_params.link_href = slurl;
|
|
|
|
LLAvatarName av_name;
|
|
if (LLAvatarNameCache::get(creator_id, &av_name))
|
|
{
|
|
// updateCreatorName(creator_id, av_name, style_params);
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
updateCreatorName(creator_id, av_name, style_params, !fRlvCanShowCreator);
|
|
// [/RLVa:KB]
|
|
}
|
|
else
|
|
{
|
|
if (mCreatorCacheConnection.connected())
|
|
{
|
|
mCreatorCacheConnection.disconnect();
|
|
}
|
|
mLabelCreatorName->setText(LLTrans::getString("None"));
|
|
// mCreatorCacheConnection = LLAvatarNameCache::get(creator_id, boost::bind(&LLSidepanelItemInfo::updateCreatorName, this, _1, _2, style_params));
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
mCreatorCacheConnection = LLAvatarNameCache::get(creator_id, boost::bind(&LLSidepanelItemInfo::updateCreatorName, this, _1, _2, style_params, !fRlvCanShowCreator));
|
|
// [/RLVa:KB]
|
|
}
|
|
|
|
getChildView("LabelCreatorTitle")->setEnabled(true);
|
|
// mLabelCreatorName->setEnabled(true);
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
mLabelCreatorName->setEnabled(fRlvCanShowCreator);
|
|
// [/RLVa:KB]
|
|
}
|
|
else
|
|
{
|
|
getChildView("LabelCreatorTitle")->setEnabled(false);
|
|
mLabelCreatorName->setEnabled(false);
|
|
mLabelCreatorName->setValue(getString("unknown_multiple"));
|
|
}
|
|
|
|
////////////////
|
|
// OWNER NAME //
|
|
////////////////
|
|
if(perm.isOwned())
|
|
{
|
|
// [RLVa:KB] - Checked: RVLa-2.0.1
|
|
bool fRlvCanShowOwner = true;
|
|
// [/RLVa:KB]
|
|
std::string slurl;
|
|
if (perm.isGroupOwned())
|
|
{
|
|
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(perm.getGroup());
|
|
|
|
slurl = LLSLURL("group", perm.getGroup(), "inspect").getSLURLString();
|
|
style_params.link_href = slurl;
|
|
if (group_data && group_data->isGroupPropertiesDataComplete())
|
|
{
|
|
mLabelOwnerName->setText(group_data->mName, style_params);
|
|
}
|
|
else
|
|
{
|
|
// Triggers refresh
|
|
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(perm.getGroup());
|
|
|
|
std::string name;
|
|
gCacheName->getGroupName(perm.getGroup(), name);
|
|
mLabelOwnerName->setText(name, style_params);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LLUUID owner_id = perm.getOwner();
|
|
// slurl = LLSLURL("agent", owner_id, "inspect").getSLURLString();
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
fRlvCanShowOwner = RlvActions::canShowName(RlvActions::SNC_DEFAULT, owner_id);
|
|
slurl = LLSLURL("agent", owner_id, (fRlvCanShowOwner) ? "inspect" : "rlvanonym").getSLURLString();
|
|
// [/RLVa:KB]
|
|
|
|
style_params.link_href = slurl;
|
|
LLAvatarName av_name;
|
|
if (LLAvatarNameCache::get(owner_id, &av_name))
|
|
{
|
|
// updateOwnerName(owner_id, av_name, style_params);
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
updateOwnerName(owner_id, av_name, style_params, !fRlvCanShowOwner);
|
|
// [/RLVa:KB]
|
|
}
|
|
else
|
|
{
|
|
if (mOwnerCacheConnection.connected())
|
|
{
|
|
mOwnerCacheConnection.disconnect();
|
|
}
|
|
mLabelOwnerName->setText(LLTrans::getString("None"));
|
|
// mOwnerCacheConnection = LLAvatarNameCache::get(owner_id, boost::bind(&LLSidepanelItemInfo::updateOwnerName, this, _1, _2, style_params));
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
mOwnerCacheConnection = LLAvatarNameCache::get(owner_id, boost::bind(&LLSidepanelItemInfo::updateOwnerName, this, _1, _2, style_params, !fRlvCanShowOwner));
|
|
// [/RLVa:KB]
|
|
}
|
|
}
|
|
getChildView("LabelOwnerTitle")->setEnabled(true);
|
|
// mLabelOwnerName->setEnabled(true);
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
mLabelOwnerName->setEnabled(fRlvCanShowOwner);
|
|
// [/RLVa:KB]
|
|
}
|
|
else
|
|
{
|
|
getChildView("LabelOwnerTitle")->setEnabled(false);
|
|
mLabelOwnerName->setEnabled(false);
|
|
mLabelOwnerName->setValue(getString("public"));
|
|
}
|
|
|
|
// Not yet supported for task inventories
|
|
mChangeThumbnailBtn->setEnabled(mObjectID.isNull() && ALEXANDRIA_LINDEN_ID != perm.getOwner());
|
|
|
|
////////////
|
|
// ORIGIN //
|
|
////////////
|
|
|
|
// <FS:Ansariel> Doesn't exist as of 04-10-2023
|
|
//if (object)
|
|
//{
|
|
// getChild<LLUICtrl>("origin")->setValue(getString("origin_inworld"));
|
|
//}
|
|
//else
|
|
//{
|
|
// getChild<LLUICtrl>("origin")->setValue(getString("origin_inventory"));
|
|
//}
|
|
|
|
//////////////////
|
|
// ACQUIRE DATE //
|
|
//////////////////
|
|
|
|
time_t time_utc = item->getCreationDate();
|
|
if (0 == time_utc)
|
|
{
|
|
getChild<LLUICtrl>("LabelAcquiredDate")->setValue(getString("unknown"));
|
|
}
|
|
else
|
|
{
|
|
std::string timeStr = getString("acquiredDate");
|
|
LLSD substitution;
|
|
substitution["datetime"] = (S32) time_utc;
|
|
LLStringUtil::format (timeStr, substitution);
|
|
getChild<LLUICtrl>("LabelAcquiredDate")->setValue(timeStr);
|
|
}
|
|
|
|
//////////////////////////////////////
|
|
// PERMISSIONS AND SALE ITEM HIDING //
|
|
//////////////////////////////////////
|
|
|
|
const std::string perm_and_sale_items[]={
|
|
//"perms_inv", // <FS:Ansariel> Doesn't exist as of 04-10-2023
|
|
"perm_modify",
|
|
"CheckOwnerModify",
|
|
"CheckOwnerCopy",
|
|
"CheckOwnerTransfer",
|
|
"GroupLabel",
|
|
"CheckShareWithGroup",
|
|
"AnyoneLabel",
|
|
"CheckEveryoneCopy",
|
|
"NextOwnerLabel",
|
|
"CheckNextOwnerModify",
|
|
"CheckNextOwnerCopy",
|
|
"CheckNextOwnerTransfer",
|
|
"CheckPurchase",
|
|
"ComboBoxSaleType",
|
|
"Edit Cost"
|
|
};
|
|
|
|
const std::string debug_items[]={
|
|
"BaseMaskDebug",
|
|
"OwnerMaskDebug",
|
|
"GroupMaskDebug",
|
|
"EveryoneMaskDebug",
|
|
"NextMaskDebug"
|
|
};
|
|
|
|
// Hide permissions checkboxes and labels and for sale info if in the trash
|
|
// or ui elements don't apply to these objects and return from function
|
|
if (!not_in_trash || cannot_restrict_permissions)
|
|
{
|
|
for(size_t t=0; t<LL_ARRAY_SIZE(perm_and_sale_items); ++t)
|
|
{
|
|
getChildView(perm_and_sale_items[t])->setVisible(false);
|
|
}
|
|
|
|
for(size_t t=0; t<LL_ARRAY_SIZE(debug_items); ++t)
|
|
{
|
|
getChildView(debug_items[t])->setVisible(false);
|
|
}
|
|
return;
|
|
}
|
|
else // Make sure perms and sale ui elements are visible
|
|
{
|
|
for(size_t t=0; t<LL_ARRAY_SIZE(perm_and_sale_items); ++t)
|
|
{
|
|
getChildView(perm_and_sale_items[t])->setVisible(true);
|
|
}
|
|
}
|
|
|
|
///////////////////////
|
|
// OWNER PERMISSIONS //
|
|
///////////////////////
|
|
|
|
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("CheckOwnerModify")->setEnabled(false);
|
|
getChild<LLUICtrl>("CheckOwnerModify")->setValue(LLSD((bool)(owner_mask & PERM_MODIFY)));
|
|
getChildView("CheckOwnerCopy")->setEnabled(false);
|
|
getChild<LLUICtrl>("CheckOwnerCopy")->setValue(LLSD((bool)(owner_mask & PERM_COPY)));
|
|
getChildView("CheckOwnerTransfer")->setEnabled(false);
|
|
getChild<LLUICtrl>("CheckOwnerTransfer")->setValue(LLSD((bool)(owner_mask & PERM_TRANSFER)));
|
|
|
|
///////////////////////
|
|
// DEBUG PERMISSIONS //
|
|
///////////////////////
|
|
|
|
if( gSavedSettings.getBOOL("DebugPermissions") )
|
|
{
|
|
childSetVisible("layout_debug_permissions", true);
|
|
|
|
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;
|
|
|
|
// <FS:Beq> remove misleading X for export when not in OpenSim
|
|
bool isOpenSim {false};
|
|
#ifdef OPENSIM
|
|
if( LLGridManager::instance().isInOpenSim() )
|
|
{
|
|
isOpenSim = true;
|
|
}
|
|
#endif
|
|
// </FS:Beq>
|
|
|
|
perm_string = "B: ";
|
|
perm_string += mask_to_string(base_mask, isOpenSim); // <FS:Beq/> remove misleading X for export when not in OpenSim
|
|
getChild<LLUICtrl>("BaseMaskDebug")->setValue(perm_string);
|
|
|
|
perm_string = "O: ";
|
|
perm_string += mask_to_string(owner_mask, isOpenSim); // <FS:Beq/> remove misleading X for export when not in OpenSim
|
|
getChild<LLUICtrl>("OwnerMaskDebug")->setValue(perm_string);
|
|
|
|
perm_string = "G";
|
|
perm_string += overwrite_group ? "*: " : ": ";
|
|
perm_string += mask_to_string(group_mask, isOpenSim); // <FS:Beq/> remove misleading X for export when not in OpenSim
|
|
getChild<LLUICtrl>("GroupMaskDebug")->setValue(perm_string);
|
|
|
|
perm_string = "E";
|
|
perm_string += overwrite_everyone ? "*: " : ": ";
|
|
perm_string += mask_to_string(everyone_mask, isOpenSim); // <FS:Beq/> remove misleading X for export when not in OpenSim
|
|
getChild<LLUICtrl>("EveryoneMaskDebug")->setValue(perm_string);
|
|
|
|
perm_string = "N";
|
|
perm_string += slam_perm ? "*: " : ": ";
|
|
perm_string += mask_to_string(next_owner_mask, isOpenSim); // <FS:Beq/> remove misleading X for export when not in OpenSim
|
|
getChild<LLUICtrl>("NextMaskDebug")->setValue(perm_string);
|
|
}
|
|
else
|
|
{
|
|
childSetVisible("layout_debug_permissions", 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);
|
|
}
|
|
|
|
// Set values.
|
|
bool is_group_copy = group_mask & PERM_COPY;
|
|
bool is_group_modify = group_mask & PERM_MODIFY;
|
|
bool is_group_move = group_mask & PERM_MOVE;
|
|
|
|
if (is_group_copy && is_group_modify && is_group_move)
|
|
{
|
|
getChild<LLUICtrl>("CheckShareWithGroup")->setValue(LLSD((bool)true));
|
|
if (LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup"))
|
|
{
|
|
ctl->setTentative(false);
|
|
}
|
|
}
|
|
else if (!is_group_copy && !is_group_modify && !is_group_move)
|
|
{
|
|
getChild<LLUICtrl>("CheckShareWithGroup")->setValue(LLSD((bool)false));
|
|
if (LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup"))
|
|
{
|
|
ctl->setTentative(false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup"))
|
|
{
|
|
ctl->setTentative(!ctl->getEnabled());
|
|
ctl->set(true);
|
|
}
|
|
}
|
|
|
|
getChild<LLUICtrl>("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<LLComboBox>("ComboBoxSaleType");
|
|
LLUICtrl* edit_cost = getChild<LLUICtrl>("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<LLUICtrl>("GroupLabel")->setEnabled(false);
|
|
getChild<LLUICtrl>("GroupLabel")->setVisible(false);
|
|
getChild<LLUICtrl>("CheckShareWithGroup")->setEnabled(false);
|
|
getChild<LLUICtrl>("CheckShareWithGroup")->setVisible(false);
|
|
getChild<LLUICtrl>("AnyoneLabel")->setEnabled(false);
|
|
getChild<LLUICtrl>("AnyoneLabel")->setVisible(false);
|
|
getChild<LLUICtrl>("CheckEveryoneCopy")->setEnabled(false);
|
|
getChild<LLUICtrl>("CheckEveryoneCopy")->setVisible(false);
|
|
getChild<LLUICtrl>("CheckPurchase")->setEnabled(false);
|
|
getChild<LLUICtrl>("CheckPurchase")->setVisible(false);
|
|
getChild<LLUICtrl>("ComboBoxSaleType")->setEnabled(false);
|
|
getChild<LLUICtrl>("ComboBoxSaleType")->setVisible(false);
|
|
getChild<LLUICtrl>("Edit Cost")->setEnabled(false);
|
|
getChild<LLUICtrl>("Edit Cost")->setVisible(false);
|
|
}
|
|
|
|
// Set values.
|
|
getChild<LLUICtrl>("CheckPurchase")->setValue(is_for_sale);
|
|
getChild<LLUICtrl>("CheckNextOwnerModify")->setValue(LLSD(bool(next_owner_mask & PERM_MODIFY)));
|
|
getChild<LLUICtrl>("CheckNextOwnerCopy")->setValue(LLSD(bool(next_owner_mask & PERM_COPY)));
|
|
getChild<LLUICtrl>("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);
|
|
}
|
|
}
|
|
|
|
//void LLSidepanelItemInfo::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params)
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
void LLSidepanelItemInfo::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params, bool rlv_restricted)
|
|
// [/RLVa:KB]
|
|
{
|
|
if (mCreatorCacheConnection.connected())
|
|
{
|
|
mCreatorCacheConnection.disconnect();
|
|
}
|
|
// std::string name = creator_name.getCompleteName();
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
std::string name = rlv_restricted ? RlvStrings::getAnonym(creator_name) : creator_name.getCompleteName();
|
|
// [/RLVa:KB]
|
|
mLabelCreatorName->setText(name, style_params);
|
|
}
|
|
|
|
//void LLSidepanelItemInfo::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params)
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
void LLSidepanelItemInfo::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params, bool rlv_restricted)
|
|
// [/RLVa:KB]
|
|
{
|
|
if (mOwnerCacheConnection.connected())
|
|
{
|
|
mOwnerCacheConnection.disconnect();
|
|
}
|
|
// std::string name = owner_name.getCompleteName();
|
|
// [RLVa:KB] - Checked: RLVa-2.0.1
|
|
std::string name = rlv_restricted ? RlvStrings::getAnonym(owner_name) : owner_name.getCompleteName();
|
|
// [/RLVa:KB]
|
|
mLabelOwnerName->setText(name, style_params);
|
|
}
|
|
|
|
void LLSidepanelItemInfo::changed(U32 mask)
|
|
{
|
|
const LLUUID& item_id = getItemID();
|
|
if (getObjectID().notNull() || item_id.isNull())
|
|
{
|
|
// Task inventory or not set up yet
|
|
return;
|
|
}
|
|
|
|
const std::set<LLUUID>& mChangedItemIDs = gInventory.getChangedIDs();
|
|
std::set<LLUUID>::const_iterator it;
|
|
|
|
for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++)
|
|
{
|
|
// set dirty for 'item profile panel' only if changed item is the item for which 'item profile panel' is shown (STORM-288)
|
|
if (*it == item_id)
|
|
{
|
|
// if there's a change we're interested in.
|
|
if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0)
|
|
{
|
|
dirty();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::dirty()
|
|
{
|
|
mIsDirty = true;
|
|
}
|
|
|
|
// static
|
|
void LLSidepanelItemInfo::onIdle( void* user_data )
|
|
{
|
|
LLSidepanelItemInfo* self = reinterpret_cast<LLSidepanelItemInfo*>(user_data);
|
|
|
|
if( self->mIsDirty )
|
|
{
|
|
self->refresh();
|
|
self->mIsDirty = false;
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::setAssociatedExperience( LLHandle<LLSidepanelItemInfo> hInfo, const LLSD& experience )
|
|
{
|
|
LLSidepanelItemInfo* info = hInfo.get();
|
|
if(info)
|
|
{
|
|
LLUUID id;
|
|
if(experience.has(LLExperienceCache::EXPERIENCE_ID))
|
|
{
|
|
id=experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
|
|
}
|
|
if(id.notNull())
|
|
{
|
|
info->getChild<LLTextBox>("LabelItemExperience")->setText(LLSLURL("experience", id, "profile").getSLURLString());
|
|
}
|
|
else
|
|
{
|
|
info->getChild<LLTextBox>("LabelItemExperience")->setText(LLTrans::getString("ExperienceNameNull"));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void LLSidepanelItemInfo::startObjectInventoryObserver()
|
|
{
|
|
if (!mObjectInventoryObserver)
|
|
{
|
|
stopObjectInventoryObserver();
|
|
|
|
// Previous object observer should be removed before starting to observe a new object.
|
|
llassert(mObjectInventoryObserver == NULL);
|
|
}
|
|
|
|
if (mObjectID.isNull())
|
|
{
|
|
LL_WARNS() << "Empty object id passed to inventory observer" << LL_ENDL;
|
|
return;
|
|
}
|
|
|
|
LLViewerObject* object = gObjectList.findObject(mObjectID);
|
|
|
|
mObjectInventoryObserver = new LLObjectInventoryObserver(this, object);
|
|
}
|
|
|
|
void LLSidepanelItemInfo::stopObjectInventoryObserver()
|
|
{
|
|
delete mObjectInventoryObserver;
|
|
mObjectInventoryObserver = NULL;
|
|
}
|
|
|
|
void LLSidepanelItemInfo::setPropertiesFieldsEnabled(bool enabled)
|
|
{
|
|
const std::string fields[] = {
|
|
"CheckOwnerModify",
|
|
"CheckOwnerCopy",
|
|
"CheckOwnerTransfer",
|
|
"CheckShareWithGroup",
|
|
"CheckEveryoneCopy",
|
|
"CheckNextOwnerModify",
|
|
"CheckNextOwnerCopy",
|
|
"CheckNextOwnerTransfer",
|
|
"CheckPurchase",
|
|
"Edit Cost"
|
|
};
|
|
for (size_t t = 0; t<LL_ARRAY_SIZE(fields); ++t)
|
|
{
|
|
getChildView(fields[t])->setEnabled(false);
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::onClickCreator()
|
|
{
|
|
LLViewerInventoryItem* 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 LLSidepanelItemInfo::onClickOwner()
|
|
{
|
|
LLViewerInventoryItem* 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 LLSidepanelItemInfo::onCommitName()
|
|
{
|
|
//LL_INFOS() << "LLSidepanelItemInfo::onCommitName()" << LL_ENDL;
|
|
LLViewerInventoryItem* item = findItem();
|
|
if(!item)
|
|
{
|
|
return;
|
|
}
|
|
LLLineEditor* labelItemName = getChild<LLLineEditor>("LabelItemName");
|
|
|
|
if(labelItemName&&
|
|
(item->getName() != labelItemName->getText()) &&
|
|
(gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) )
|
|
{
|
|
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
|
|
new_item->rename(labelItemName->getText());
|
|
onCommitChanges(new_item);
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::onCommitDescription()
|
|
{
|
|
//LL_INFOS() << "LLSidepanelItemInfo::onCommitDescription()" << LL_ENDL;
|
|
LLViewerInventoryItem* item = findItem();
|
|
if(!item) return;
|
|
|
|
LLTextEditor* labelItemDesc = getChild<LLTextEditor>("LabelItemDesc");
|
|
if(!labelItemDesc)
|
|
{
|
|
return;
|
|
}
|
|
if((item->getDescription() != labelItemDesc->getText()) &&
|
|
(gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)))
|
|
{
|
|
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
|
|
|
|
new_item->setDescription(labelItemDesc->getText());
|
|
onCommitChanges(new_item);
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::onCommitPermissions(LLUICtrl* ctrl)
|
|
{
|
|
if (ctrl)
|
|
{
|
|
// will be enabled by response from server
|
|
ctrl->setEnabled(false);
|
|
}
|
|
updatePermissions();
|
|
}
|
|
|
|
void LLSidepanelItemInfo::updatePermissions()
|
|
{
|
|
LLViewerInventoryItem* item = findItem();
|
|
if(!item) return;
|
|
|
|
bool is_group_owned;
|
|
LLUUID owner_id;
|
|
LLUUID group_id;
|
|
LLPermissions perm(item->getPermissions());
|
|
perm.getOwnership(owner_id, is_group_owned);
|
|
|
|
if (is_group_owned && gAgent.hasPowerInGroup(owner_id, GP_OBJECT_MANIPULATE))
|
|
{
|
|
group_id = owner_id;
|
|
}
|
|
|
|
LLCheckBoxCtrl* CheckShareWithGroup = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
|
|
|
|
if(CheckShareWithGroup)
|
|
{
|
|
perm.setGroupBits(gAgent.getID(), group_id,
|
|
CheckShareWithGroup->get(),
|
|
PERM_MODIFY | PERM_MOVE | PERM_COPY);
|
|
}
|
|
LLCheckBoxCtrl* CheckEveryoneCopy = getChild<LLCheckBoxCtrl>("CheckEveryoneCopy");
|
|
if(CheckEveryoneCopy)
|
|
{
|
|
perm.setEveryoneBits(gAgent.getID(), group_id,
|
|
CheckEveryoneCopy->get(), PERM_COPY);
|
|
}
|
|
|
|
LLCheckBoxCtrl* CheckNextOwnerModify = getChild<LLCheckBoxCtrl>("CheckNextOwnerModify");
|
|
if(CheckNextOwnerModify)
|
|
{
|
|
perm.setNextOwnerBits(gAgent.getID(), group_id,
|
|
CheckNextOwnerModify->get(), PERM_MODIFY);
|
|
}
|
|
LLCheckBoxCtrl* CheckNextOwnerCopy = getChild<LLCheckBoxCtrl>("CheckNextOwnerCopy");
|
|
if(CheckNextOwnerCopy)
|
|
{
|
|
perm.setNextOwnerBits(gAgent.getID(), group_id,
|
|
CheckNextOwnerCopy->get(), PERM_COPY);
|
|
}
|
|
LLCheckBoxCtrl* CheckNextOwnerTransfer = getChild<LLCheckBoxCtrl>("CheckNextOwnerTransfer");
|
|
if(CheckNextOwnerTransfer)
|
|
{
|
|
perm.setNextOwnerBits(gAgent.getID(), group_id,
|
|
CheckNextOwnerTransfer->get(), PERM_TRANSFER);
|
|
}
|
|
if(perm != item->getPermissions()
|
|
&& item->isFinished())
|
|
{
|
|
LLPointer<LLViewerInventoryItem> 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);
|
|
onCommitChanges(new_item);
|
|
}
|
|
else
|
|
{
|
|
// need to make sure we don't just follow the click
|
|
refresh();
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::onEditThumbnail()
|
|
{
|
|
LLSD data;
|
|
data["task_id"] = mObjectID;
|
|
data["item_id"] = mItemID;
|
|
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
|
}
|
|
|
|
void LLSidepanelItemInfo::onCommitSaleInfo(LLUICtrl* ctrl)
|
|
{
|
|
if (ctrl)
|
|
{
|
|
// will be enabled by response from server
|
|
ctrl->setEnabled(false);
|
|
}
|
|
//LL_INFOS() << "LLSidepanelItemInfo::onCommitSaleInfo()" << LL_ENDL;
|
|
updateSaleInfo();
|
|
}
|
|
|
|
void LLSidepanelItemInfo::updateSaleInfo()
|
|
{
|
|
LLViewerInventoryItem* item = findItem();
|
|
if(!item) return;
|
|
LLSaleInfo sale_info(item->getSaleInfo());
|
|
if(!gAgent.allowOperation(PERM_TRANSFER, item->getPermissions(), GP_OBJECT_SET_SALE))
|
|
{
|
|
getChild<LLUICtrl>("CheckPurchase")->setValue(LLSD((bool)false));
|
|
}
|
|
|
|
if((bool)getChild<LLUICtrl>("CheckPurchase")->getValue())
|
|
{
|
|
// turn on sale info
|
|
LLSaleInfo::EForSale sale_type = LLSaleInfo::FS_COPY;
|
|
|
|
LLComboBox* combo_sale_type = getChild<LLComboBox>("ComboBoxSaleType");
|
|
if (combo_sale_type)
|
|
{
|
|
sale_type = static_cast<LLSaleInfo::EForSale>(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<LLUICtrl>("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<LLViewerInventoryItem> 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);
|
|
onCommitChanges(new_item);
|
|
}
|
|
else
|
|
{
|
|
// need to make sure we don't just follow the click
|
|
refresh();
|
|
}
|
|
}
|
|
|
|
void LLSidepanelItemInfo::onCommitChanges(LLPointer<LLViewerInventoryItem> item)
|
|
{
|
|
if (item.isNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mObjectID.isNull())
|
|
{
|
|
// This is in the agent's inventory.
|
|
// Mark update as pending and wait only for most recent one in case user requested for couple
|
|
// Once update arrives or any of ids change drop pending id.
|
|
mUpdatePendingId++;
|
|
LLPointer<LLInventoryCallback> callback = new PropertiesChangedCallback(getHandle(), mItemID, mUpdatePendingId);
|
|
update_inventory_item(item.get(), callback);
|
|
//item->updateServer(false);
|
|
gInventory.updateItem(item);
|
|
gInventory.notifyObservers();
|
|
}
|
|
else
|
|
{
|
|
// This is in an object's contents.
|
|
LLViewerObject* object = gObjectList.findObject(mObjectID);
|
|
if (object)
|
|
{
|
|
object->updateInventory(
|
|
item,
|
|
TASK_INVENTORY_ITEM_KEY,
|
|
false);
|
|
|
|
if (object->isSelected())
|
|
{
|
|
// Since object is selected (build floater is open) object will
|
|
// receive properties update, detect serial mismatch, dirty and
|
|
// reload inventory, meanwhile some other updates will refresh it.
|
|
// So mark dirty early, this will prevent unnecessary changes
|
|
// and download will be triggered by LLPanelObjectInventory - it
|
|
// prevents flashing in content tab and some duplicated request.
|
|
object->dirtyInventory();
|
|
}
|
|
setPropertiesFieldsEnabled(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
LLViewerInventoryItem* LLSidepanelItemInfo::findItem() const
|
|
{
|
|
LLViewerInventoryItem* item = NULL;
|
|
if(mObjectID.isNull())
|
|
{
|
|
// it is in agent inventory
|
|
item = gInventory.getItem(mItemID);
|
|
}
|
|
else
|
|
{
|
|
LLViewerObject* object = gObjectList.findObject(mObjectID);
|
|
if(object)
|
|
{
|
|
item = static_cast<LLViewerInventoryItem*>(object->getInventoryObject(mItemID));
|
|
}
|
|
}
|
|
return item;
|
|
}
|
|
|
|
// virtual
|
|
void LLSidepanelItemInfo::save()
|
|
{
|
|
onCommitName();
|
|
onCommitDescription();
|
|
updatePermissions();
|
|
updateSaleInfo();
|
|
}
|