summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-03-29 21:30:46 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-03-29 21:39:51 +0300
commit8ed39a469b1b7337855c113f785fb64e66cf3b8f (patch)
treed861464f52d7551d362fd9451e830eb79d9e5bcf /indra
parenta6b71d3b8234261f4ed3674017736d04649ea992 (diff)
SL-19504 Allow drag and drop of textures into thumbnail floater
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llfloaterchangeitemthumbnail.cpp151
-rw-r--r--indra/newview/llfloaterchangeitemthumbnail.h21
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml11
3 files changed, 166 insertions, 17 deletions
diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp
index a10de8ba23..8f6d984aa9 100644
--- a/indra/newview/llfloaterchangeitemthumbnail.cpp
+++ b/indra/newview/llfloaterchangeitemthumbnail.cpp
@@ -45,6 +45,7 @@
#include "llviewerfoldertype.h"
#include "llviewermenufile.h"
#include "llviewerobjectlist.h"
+#include "llviewertexturelist.h"
#include "llwindow.h"
@@ -169,6 +170,53 @@ void LLFloaterChangeItemThumbnail::onOpen(const LLSD& key)
refreshFromInventory();
}
+void LLFloaterChangeItemThumbnail::onFocusReceived()
+{
+ mPasteFromClipboardBtn->setEnabled(LLClipboard::instance().hasContents());
+}
+
+void LLFloaterChangeItemThumbnail::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ mPasteFromClipboardBtn->setEnabled(LLClipboard::instance().hasContents());
+}
+
+BOOL LLFloaterChangeItemThumbnail::handleDragAndDrop(
+ S32 x,
+ S32 y,
+ MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg)
+{
+ if (cargo_type == DAD_TEXTURE)
+ {
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+ if (item->getAssetUUID().notNull())
+ {
+ if (drop)
+ {
+ assignAndValidateAsset(item->getAssetUUID());
+ }
+
+ *accept = ACCEPT_YES_SINGLE;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+
+ LL_DEBUGS("UserInput") << "dragAndDrop handled by LLFloaterChangeItemThumbnail " << getKey() << LL_ENDL;
+
+ return TRUE;
+}
+
void LLFloaterChangeItemThumbnail::changed(U32 mask)
{
//LLInventoryObserver
@@ -342,9 +390,11 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj)
mThumbnailCtrl->setValue(thumbnail_id);
mCopyToClipboardBtn->setEnabled(thumbnail_id.notNull());
+ mPasteFromClipboardBtn->setEnabled(LLClipboard::instance().hasContents());
// todo: some elements might not support setting thumbnails
// since they already have them
+ // It is unclear how system folders should function
}
void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata)
@@ -418,7 +468,8 @@ void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata)
LLInventoryObject* obj = self->getInventoryObject();
if (obj)
{
- LLClipboard::instance().addToClipboard(obj->getThumbnailUUID());
+ LLClipboard::instance().addToClipboard(obj->getThumbnailUUID(), LLAssetType::AT_NONE);
+ self->mPasteFromClipboardBtn->setEnabled(true);
}
}
@@ -440,29 +491,29 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata)
// no point checking snapshot?
if (item->getType() == LLAssetType::AT_TEXTURE)
{
- asset_id = item->getAssetUUID();
+ bool copy = item->getPermissions().allowCopyBy(gAgent.getID());
+ bool xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+
+ if (copy && xfer)
+ {
+ asset_id = item->getAssetUUID();
+ }
+ else
+ {
+ LLNotificationsUtil::add("ThumbnailInsufficientPermissions");
+ return;
+ }
}
}
else
{
- LLPointer<LLViewerFetchedTexture> texturep = LLViewerTextureManager::getFetchedTexture(potential_uuid);
- if (texturep)
- {
- asset_id = potential_uuid;
- }
+ // assume that this is a texture
+ asset_id = potential_uuid;
}
}
if (asset_id.notNull())
{
- // todo: if texture isn't loaded subscribe, or preload it in some way.
- if (validateAsset(asset_id))
- {
- self->setThumbnailId(asset_id);
- }
- else
- {
- LLNotificationsUtil::add("ThumbnailDimentionsLimit");
- }
+ self->assignAndValidateAsset(asset_id);
}
// else show 'buffer has no texture' warning?
}
@@ -489,15 +540,45 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio
}
}
-bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id)
+void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id)
{
LLPointer<LLViewerFetchedTexture> texturep = LLViewerTextureManager::getFetchedTexture(asset_id);
+ if (texturep->getFullWidth() == 0 && !texturep->isFullyLoaded() && !texturep->isMissingAsset())
+ {
+ texturep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL, // don't actually need max one, 3 or 4 should be enough
+ FALSE,
+ FALSE,
+ new LLHandle<LLFloater>(getHandle()),
+ NULL,
+ FALSE);
+ }
+ else
+ {
+ if (validateAsset(asset_id))
+ {
+ setThumbnailId(asset_id);
+ }
+ else
+ {
+ LLNotificationsUtil::add("ThumbnailDimentionsLimit");
+ }
+ }
+}
+bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id)
+{
+ LLPointer<LLViewerFetchedTexture> texturep = LLViewerTextureManager::findFetchedTexture(asset_id, TEX_LIST_STANDARD);
if (!texturep)
{
return false;
}
+ if (texturep->isMissingAsset())
+ {
+ return false;
+ }
+
if (texturep->getFullWidth() != texturep->getFullHeight())
{
return false;
@@ -517,6 +598,42 @@ bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id)
return true;
}
+//static
+void LLFloaterChangeItemThumbnail::onImageLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ if (!userdata) return;
+
+ if (!final && success) return; //not done yet
+
+ LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata;
+
+ if (success && !handle->isDead())
+ {
+ LLFloaterChangeItemThumbnail* self = static_cast<LLFloaterChangeItemThumbnail*>(handle->get());
+ if (self)
+ {
+ LLUUID asset_id = src_vi->getID();
+ if (validateAsset(asset_id))
+ {
+ self->setThumbnailId(asset_id);
+ }
+ else
+ {
+ LLNotificationsUtil::add("ThumbnailDimentionsLimit");
+ }
+ }
+ }
+
+ delete handle;
+}
+
void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id)
{
// show hourglass cursor when loading inventory window
diff --git a/indra/newview/llfloaterchangeitemthumbnail.h b/indra/newview/llfloaterchangeitemthumbnail.h
index 50c0c951d4..18cf2f7a85 100644
--- a/indra/newview/llfloaterchangeitemthumbnail.h
+++ b/indra/newview/llfloaterchangeitemthumbnail.h
@@ -37,6 +37,7 @@ class LLTextBox;
class LLThumbnailCtrl;
class LLUICtrl;
class LLViewerInventoryItem;
+class LLViewerFetchedTexture;
class LLFloaterChangeItemThumbnail : public LLFloater, public LLInventoryObserver, public LLVOInventoryListener
{
@@ -46,6 +47,18 @@ public:
BOOL postBuild() override;
void onOpen(const LLSD& key) override;
+ void onFocusReceived() override;
+ void onMouseEnter(S32 x, S32 y, MASK mask) override;
+
+ BOOL handleDragAndDrop(
+ S32 x,
+ S32 y,
+ MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg) override;
void changed(U32 mask) override;
void inventoryChanged(LLViewerObject* object,
@@ -67,7 +80,15 @@ private:
static void onRemove(void*);
static void onRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFloater> handle);
+ void assignAndValidateAsset(const LLUUID &asset_id);
static bool validateAsset(const LLUUID &asset_id);
+ static void onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
void showTexturePicker(const LLUUID &thumbnail_id);
void onTexturePickerCommit(LLUUID id);
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 0ea13e7d63..73ce5a6096 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6144,6 +6144,17 @@ Are you sure you want to delete them?
</notification>
<notification
+ icon="alertmodal.tga"
+ name="ThumbnailInsufficientPermissions"
+ type="alertmodal">
+ <unique/>
+ Only copy and transfer free images can be assigned as thumbnails.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="ConfirmUnlink"
type="alertmodal">