summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorandreykproductengine <andreykproductengine@lindenlab.com>2019-12-11 22:48:46 +0200
committerandreykproductengine <andreykproductengine@lindenlab.com>2019-12-11 22:48:46 +0200
commiteaa4e977d687abbfb28687c66cb0b92e66deb484 (patch)
tree71dd0e771853413e9457d17516870a70f1fe3c0b /indra
parentb3d57f93b6c445578ea3f4caf596472f4ee6fa43 (diff)
SL-12334 [Copypaste] Texture is not copied to clipboard from a full-perms object
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llpanelface.cpp69
-rw-r--r--indra/newview/llpanelobject.cpp42
-rw-r--r--indra/newview/llpanelobject.h6
3 files changed, 73 insertions, 44 deletions
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 3a48db0a1a..914863ccc0 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -2922,15 +2922,24 @@ void LLPanelFace::onCopyFaces()
if (te_data["te"].has("imageid"))
{
+ LLUUID item_id;
LLUUID id = te_data["te"]["imageid"].asUUID();
- // Doesn't support local images!
- if (id.isNull() || !LLPanelObject::canCopyTexture(id))
+ bool full_perm = LLPanelObject::isLibraryTexture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify());
+
+ // todo: fix this, we are often searching same tuxture multiple times (equal to number of faces)
+ if (id.notNull() && !full_perm)
{
- if (LLLocalBitmapMgr::getInstance()->isLocalBitmap(id))
- {
- te_data["te"]["imageid"] = id;
- }
- else
+ // What this does is simply searches inventory for item with same asset id,
+ // as result it is Hightly unreliable, leaves little control to user, borderline hack
+ // but there are little options to preserve permissions - multiple inventory
+ // items might reference same asset and inventory search is expensive.
+ item_id = LLPanelObject::getCopyPermInventoryTextureId(id);
+ }
+
+ if (id.isNull()
+ || (!full_perm && item_id.isNull()))
+ {
+ if (!LLLocalBitmapMgr::getInstance()->isLocalBitmap(id))
{
te_data["te"].erase("imageid");
te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
@@ -2939,23 +2948,30 @@ void LLPanelFace::onCopyFaces()
}
else
{
- te_data["te"]["itemfullperm"] = false; // if item is not in inventory, we won't get here
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
- LLUUID item_id = texture_ctrl->getImageItemID();
- if (item_id.notNull())
+ te_data["te"]["itemfullperm"] = full_perm;
+ // If full permission object, texture is free to copy,
+ // but otherwise we need to check inventory and extract permissions
+ //
+ // Normally we care only about restrictions for current user and objects
+ // don't inherit any 'next owner' permissions from texture, so there is
+ // no need to record item id if full_perm==true
+ if (!full_perm && item_id.notNull())
{
- // Texture control should have the id (otherwise canCopyTexture == false),
- // use it for consistency.
- te_data["te"]["imageitemid"] = item_id;
-
LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
if (itemp)
{
- te_data["te"]["itemfullperm"] = itemp->getIsFullPerm();
- if (!itemp->isFinished())
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
{
- // needed for dropTextureAllFaces
- LLInventoryModelBackgroundFetch::instance().start(item_id, false);
+ te_data["te"]["imageitemid"] = item_id;
+ te_data["te"]["itemfullperm"] = itemp->getIsFullPerm();
+ if (!itemp->isFinished())
+ {
+ // needed for dropTextureAllFaces
+ LLInventoryModelBackgroundFetch::instance().start(item_id, false);
+ }
}
}
}
@@ -3041,6 +3057,7 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te)
if (te_data.has("te"))
{
// Texture
+ bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean();
if (mPasteDiffuse && te_data["te"].has("imageid"))
{
const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id
@@ -3061,8 +3078,9 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te)
}
// for case when item got removed from inventory after we pressed 'copy'
- if (!itemp_res)
+ if (!itemp_res && !full_perm)
{
+ // todo: fix this, we are often searching same tuxter multiple times (equal to number of faces)
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
LLAssetIDMatches asset_id_matches(imageid);
@@ -3111,14 +3129,11 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te)
}
}
// not an inventory item or no complete items
- else if (te_data["te"].has("itemfullperm"))
+ else if (full_perm)
{
- if (te_data["te"]["itemfullperm"].asBoolean())
- {
- // when user clicked copy, item existed in inventory as fullperm (also can be used for local images)
- LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- objectp->setTEImage(U8(te), image);
- }
+ // Either library, local or existed as fullperm when user made a copy
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ objectp->setTEImage(U8(te), image);
}
}
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index b99c77fb79..b179b1be53 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -2503,32 +2503,31 @@ bool LLPanelObject::pasteEnabletMenuItem(const LLSD& userdata)
return true;
}
-// Static
-bool LLPanelObject::canCopyTexture(LLUUID image_id)
+//static
+bool LLPanelObject::isLibraryTexture(LLUUID image_id)
{
- // User is allowed to copy a texture if:
- // library asset or default texture,
- // or copy perm asset exists in user's inventory
-
- // Library asset or default texture
if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID())
- || image_id == LLUUID(gSavedSettings.getString( "DefaultObjectTexture" ))
- || image_id == LLUUID(gSavedSettings.getString( "UIImgWhiteUUID" ))
- || image_id == LLUUID(gSavedSettings.getString( "UIImgInvisibleUUID" ))
+ || image_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture"))
+ || image_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID"))
+ || image_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID"))
|| image_id == LLUUID(SCULPT_DEFAULT_TEXTURE))
{
return true;
}
+ return false;
+}
- // Search for a copy perm asset
+//static
+LLUUID LLPanelObject::getCopyPermInventoryTextureId(LLUUID image_id)
+{
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
LLAssetIDMatches asset_id_matches(image_id);
gInventory.collectDescendentsIf(LLUUID::null,
- cats,
- items,
- LLInventoryModel::INCLUDE_TRASH,
- asset_id_matches);
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
if (items.size())
{
for (S32 i = 0; i < items.size(); i++)
@@ -2541,11 +2540,20 @@ bool LLPanelObject::canCopyTexture(LLUUID image_id)
gAgent.getID(),
gAgent.getGroupID()))
{
- return true;
+ return itemp->getUUID();
}
}
}
}
+ return LLUUID::null;
+}
- return false;
+// Static
+bool LLPanelObject::canCopyTexture(LLUUID image_id)
+{
+ // User is allowed to copy a texture if:
+ // library asset or default texture,
+ // or copy perm asset exists in user's inventory
+
+ return isLibraryTexture(image_id) || getCopyPermInventoryTextureId(image_id).notNull();
}
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 0c37e837ad..65f46a8ed3 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -88,6 +88,12 @@ public:
bool pasteCheckMenuItem(const LLSD& userdata);
void pasteDoMenuItem(const LLSD& userdata);
bool pasteEnabletMenuItem(const LLSD& userdata);
+ static bool isLibraryTexture(LLUUID image_id);
+
+ // Finds copy-enabled texture with specified asset from inventory
+ // This can be performance unfriendly and doesn't warranty that
+ // the texture is original source of asset
+ static LLUUID getCopyPermInventoryTextureId(LLUUID image_id);
static bool canCopyTexture(LLUUID image_id);
protected: