summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-02-17 01:28:42 +0200
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2024-02-20 19:05:54 +0200
commita657b9b52d2818e2ba5b36ab3c58d0025dcb08e3 (patch)
tree96dd8453de69cc995b9318bb3eaca7ab172ea5c3 /indra/newview
parent8be121e7cd88e692dad26510426defc5fc1df358 (diff)
jira-archive-internal#71115 Add Images to Objects in Bulk
SL-20725
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfloaterchangeitemthumbnail.cpp175
-rw-r--r--indra/newview/llfloaterchangeitemthumbnail.h7
-rw-r--r--indra/newview/llfloatersimplesnapshot.cpp39
-rw-r--r--indra/newview/llfloatersimplesnapshot.h19
-rw-r--r--indra/newview/llinventoryfunctions.cpp17
-rw-r--r--indra/newview/llinventorygallerymenu.cpp6
6 files changed, 213 insertions, 50 deletions
diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp
index 0301627c15..c328c0b8f6 100644
--- a/indra/newview/llfloaterchangeitemthumbnail.cpp
+++ b/indra/newview/llfloaterchangeitemthumbnail.cpp
@@ -52,26 +52,32 @@
class LLThumbnailImagePicker : public LLFilePickerThread
{
public:
- LLThumbnailImagePicker(const LLUUID &item_id);
- LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id);
+ LLThumbnailImagePicker(const LLUUID &item_id, LLFloaterSimpleSnapshot::completion_t callback);
+ LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id, LLFloaterSimpleSnapshot::completion_t callback);
~LLThumbnailImagePicker();
void notify(const std::vector<std::string>& filenames) override;
private:
LLUUID mInventoryId;
LLUUID mTaskId;
+ LLFloaterSimpleSnapshot::completion_t mCallback;
};
-LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id)
+LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id,
+ LLFloaterSimpleSnapshot::completion_t callback)
: LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE)
, mInventoryId(item_id)
+ , mCallback(callback)
{
}
-LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id)
+LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id,
+ const LLUUID &task_id,
+ LLFloaterSimpleSnapshot::completion_t callback)
: LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE)
, mInventoryId(item_id)
, mTaskId(task_id)
+ , mCallback(callback)
{
}
@@ -91,7 +97,7 @@ void LLThumbnailImagePicker::notify(const std::vector<std::string>& filenames)
return;
}
- LLFloaterSimpleSnapshot::uploadThumbnail(file_path, mInventoryId, mTaskId);
+ LLFloaterSimpleSnapshot::uploadThumbnail(file_path, mInventoryId, mTaskId, mCallback);
}
LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key)
@@ -152,18 +158,34 @@ BOOL LLFloaterChangeItemThumbnail::postBuild()
void LLFloaterChangeItemThumbnail::onOpen(const LLSD& key)
{
- if (!key.has("item_id") && !key.isUUID())
+ if (!key.has("item_id") && !key.isUUID() && !key.isArray())
{
closeFloater();
}
- if (key.isUUID())
+
+ mItemList.clear();
+ if (key.isArray())
+ {
+ if (key.size() > 30)
+ {
+ // incident avoidance
+ // Todo: Show notification
+ closeFloater();
+ }
+
+ for (LLSD::array_const_iterator it = key.beginArray(); it != key.endArray(); ++it)
+ {
+ mItemList.insert(it->asUUID());
+ }
+ }
+ else if (key.isUUID())
{
- mItemId = key.asUUID();
+ mItemList.insert(key.asUUID());
}
else
{
- mItemId = key["item_id"].asUUID();
+ mItemList.insert(key["item_id"].asUUID());
mTaskId = key["task_id"].asUUID();
}
@@ -221,7 +243,7 @@ void LLFloaterChangeItemThumbnail::changed(U32 mask)
{
//LLInventoryObserver
- if (mTaskId.notNull() || mItemId.isNull())
+ if (mTaskId.notNull() || mItemList.size() == 0)
{
// Task inventory or not set up yet
return;
@@ -229,13 +251,13 @@ void LLFloaterChangeItemThumbnail::changed(U32 mask)
const std::set<LLUUID>& mChangedItemIDs = gInventory.getChangedIDs();
std::set<LLUUID>::const_iterator it;
+ const LLUUID expected_id = *mItemList.begin();
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 == mItemId)
+ // check if there's a change we're interested in.
+ if (*it == expected_id)
{
- // if there's a change we're interested in.
if ((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0)
{
refreshFromInventory();
@@ -255,6 +277,12 @@ void LLFloaterChangeItemThumbnail::inventoryChanged(LLViewerObject* object,
LLInventoryObject* LLFloaterChangeItemThumbnail::getInventoryObject()
{
+ if (mItemList.size() == 0)
+ {
+ return NULL;
+ }
+
+ const LLUUID item_id = *mItemList.begin();
LLInventoryObject* obj = NULL;
if (mTaskId.isNull())
{
@@ -265,7 +293,7 @@ LLInventoryObject* LLFloaterChangeItemThumbnail::getInventoryObject()
mObserverInitialized = true;
}
- obj = gInventory.getObject(mItemId);
+ obj = gInventory.getObject(item_id);
}
else
{
@@ -278,7 +306,7 @@ LLInventoryObject* LLFloaterChangeItemThumbnail::getInventoryObject()
mObserverInitialized = false;
}
- obj = object->getInventoryObject(mItemId);
+ obj = object->getInventoryObject(item_id);
}
}
return obj;
@@ -357,7 +385,7 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj)
LLInventoryModel::item_array_t items;
// Not LLIsOfAssetType, because we allow links
LLIsOutfitTextureType f;
- gInventory.getDirectDescendentsOf(mItemId, cats, items, f);
+ gInventory.getDirectDescendentsOf(*mItemList.begin(), cats, items, f);
if (1 == items.size())
{
@@ -401,7 +429,16 @@ void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata)
{
LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata;
- (new LLThumbnailImagePicker(self->mItemId, self->mTaskId))->getFile();
+ LLUUID task_id = self->mTaskId;
+ uuid_set_t inventory_ids = self->mItemList;
+ (new LLThumbnailImagePicker(
+ *self->mItemList.begin(),
+ self->mTaskId,
+ [inventory_ids, task_id](const LLUUID& asset_id)
+ {
+ onUploadComplete(asset_id, task_id, inventory_ids);
+ }
+ ))->getFile();
LLFloater* floaterp = self->mPickerHandle.get();
if (floaterp)
@@ -428,7 +465,7 @@ void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata)
else
{
LLSD key;
- key["item_id"] = self->mItemId;
+ key["item_id"] = *self->mItemList.begin();
key["task_id"] = self->mTaskId;
LLFloaterSimpleSnapshot* snapshot_floater = (LLFloaterSimpleSnapshot*)LLFloaterReg::showInstance("simple_snapshot", key, true);
if (snapshot_floater)
@@ -436,6 +473,13 @@ void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata)
self->addDependentFloater(snapshot_floater);
self->mSnapshotHandle = snapshot_floater->getHandle();
snapshot_floater->setOwner(self);
+ LLUUID task_id = self->mTaskId;
+ uuid_set_t inventory_ids = self->mItemList;
+ snapshot_floater->setComplectionCallback(
+ [inventory_ids, task_id](const LLUUID& asset_id)
+ {
+ onUploadComplete(asset_id, task_id, inventory_ids);
+ });
}
}
@@ -532,7 +576,7 @@ void LLFloaterChangeItemThumbnail::onRemove(void *userdata)
LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata;
LLSD payload;
- payload["item_id"] = self->mItemId;
+ payload["item_id"] = *self->mItemList.begin();
payload["object_id"] = self->mTaskId;
LLNotificationsUtil::add("DeleteThumbnail", LLSD(), payload, boost::bind(&LLFloaterChangeItemThumbnail::onRemovalConfirmation, _1, _2, self->getHandle()));
}
@@ -551,7 +595,8 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio
struct ImageLoadedData
{
LLUUID mThumbnailId;
- LLUUID mObjectId;
+ LLUUID mTaskId;
+ uuid_set_t mItemIds;
LLHandle<LLFloater> mFloaterHandle;
bool mSilent;
// Keep image reference to prevent deletion on timeout
@@ -581,7 +626,8 @@ void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id
mExpectingAssetId = asset_id;
}
ImageLoadedData *data = new ImageLoadedData();
- data->mObjectId = mItemId;
+ data->mTaskId = mTaskId;
+ data->mItemIds = mItemList;
data->mThumbnailId = asset_id;
data->mFloaterHandle = getHandle();
data->mSilent = silent;
@@ -663,10 +709,13 @@ void LLFloaterChangeItemThumbnail::onImageDataLoaded(
if (success)
{
- // Update the item, set it even if floater is dead
+ // Update items, set thumnails even if floater is dead
if (validateAsset(data->mThumbnailId))
{
- setThumbnailId(data->mThumbnailId, data->mObjectId);
+ for (const LLUUID& id : data->mItemIds)
+ {
+ setThumbnailId(data->mThumbnailId, data->mTaskId, id);
+ }
}
else if (!data->mSilent)
{
@@ -716,11 +765,22 @@ void LLFloaterChangeItemThumbnail::onFullImageLoaded(
}
else if (src_vi->getFullWidth() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX)
{
- LLFloaterSimpleSnapshot::uploadThumbnail(src, data->mObjectId, LLUUID::null);
+ LLUUID task_id = data->mTaskId;
+ uuid_set_t inventory_ids = data->mItemIds;
+ LLFloaterSimpleSnapshot::uploadThumbnail(src,
+ *data->mItemIds.begin(),
+ task_id,
+ [inventory_ids, task_id](const LLUUID& asset_id)
+ {
+ onUploadComplete(asset_id, task_id, inventory_ids);
+ });
}
else
{
- setThumbnailId(data->mThumbnailId, data->mObjectId);
+ for (const LLUUID& id : data->mItemIds)
+ {
+ setThumbnailId(data->mThumbnailId, data->mTaskId, id);
+ }
}
}
@@ -837,19 +897,33 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit()
&& (texturep->getCachedRawImageLevel() == 0 || texturep->getRawImageLevel() == 0)
&& (texturep->isCachedRawImageReady() || texturep->isRawImageValid()))
{
+ LLUUID task_id = mTaskId;
+ uuid_set_t inventory_ids = mItemList;
+ LLFloaterSimpleSnapshot::completion_t callback =
+ [inventory_ids, task_id](const LLUUID& asset_id)
+ {
+ onUploadComplete(asset_id, task_id, inventory_ids);
+ };
if (texturep->isRawImageValid())
{
- LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getRawImage(), mItemId, mTaskId);
+ LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getRawImage(),
+ *mItemList.begin(),
+ mTaskId,
+ callback);
}
else
{
- LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getCachedRawImage(), mItemId, mTaskId);
+ LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getCachedRawImage(),
+ *mItemList.begin(),
+ mTaskId,
+ callback);
}
}
else
{
ImageLoadedData* data = new ImageLoadedData();
- data->mObjectId = mItemId;
+ data->mTaskId = mTaskId;
+ data->mItemIds = mItemList;
data->mThumbnailId = asset_id;
data->mFloaterHandle = getHandle();
data->mSilent = false;
@@ -873,6 +947,29 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit()
}
}
+//static
+void LLFloaterChangeItemThumbnail::onUploadComplete(const LLUUID& asset_id, const LLUUID& task_id, const uuid_set_t& inventory_ids)
+{
+ if (asset_id.isNull())
+ {
+ // failure
+ return;
+ }
+ uuid_set_t::iterator iter = inventory_ids.begin();
+ uuid_set_t::iterator end = inventory_ids.end();
+ if (iter == end)
+ {
+ LL_WARNS() << "Received empty item list!" << LL_ENDL;
+ }
+ else
+ {
+ iter++; // first element was set by upload
+ for (; iter != end; iter++)
+ {
+ setThumbnailId(asset_id, task_id, *iter);
+ }
+ }
+}
void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID &new_thumbnail_id)
{
@@ -888,20 +985,28 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID &new_thumbnail_id
return;
}
- setThumbnailId(new_thumbnail_id, mItemId, obj);
+ for (const LLUUID &id : mItemList)
+ {
+ setThumbnailId(new_thumbnail_id, id, obj);
+ }
}
-void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id)
+void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& task_id, const LLUUID& inv_obj_id)
{
- LLInventoryObject* obj = gInventory.getObject(object_id);
+ if (task_id.notNull())
+ {
+ LL_WARNS() << "Not supported" << LL_ENDL;
+ return;
+ }
+ LLInventoryObject* obj = gInventory.getObject(inv_obj_id);
if (!obj)
{
return;
}
- setThumbnailId(new_thumbnail_id, object_id, obj);
+ setThumbnailId(new_thumbnail_id, inv_obj_id, obj);
}
-void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id, LLInventoryObject* obj)
+void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& inv_obj_id, LLInventoryObject* obj)
{
if (obj->getThumbnailUUID() != new_thumbnail_id)
{
@@ -919,12 +1024,12 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id
LLViewerInventoryCategory* view_folder = dynamic_cast<LLViewerInventoryCategory*>(obj);
if (view_folder)
{
- update_inventory_category(object_id, updates, NULL);
+ update_inventory_category(inv_obj_id, updates, NULL);
}
LLViewerInventoryItem* view_item = dynamic_cast<LLViewerInventoryItem*>(obj);
if (view_item)
{
- update_inventory_item(object_id, updates, NULL);
+ update_inventory_item(inv_obj_id, updates, NULL);
}
}
}
diff --git a/indra/newview/llfloaterchangeitemthumbnail.h b/indra/newview/llfloaterchangeitemthumbnail.h
index a91e9b8ee9..16d60ab56a 100644
--- a/indra/newview/llfloaterchangeitemthumbnail.h
+++ b/indra/newview/llfloaterchangeitemthumbnail.h
@@ -100,10 +100,11 @@ private:
void showTexturePicker(const LLUUID &thumbnail_id);
void onTexturePickerCommit();
+ static void onUploadComplete(const LLUUID& asset_id, const LLUUID& task_id, const uuid_set_t& inventory_ids);
void setThumbnailId(const LLUUID &new_thumbnail_id);
- static void setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id);
- static void setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id, LLInventoryObject* obj);
+ static void setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& task_id, const LLUUID& inv_obj_id);
+ static void setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& inv_obj_id, LLInventoryObject* obj);
enum EToolTipState
{
@@ -121,7 +122,7 @@ private:
bool mObserverInitialized;
EToolTipState mTooltipState;
- LLUUID mItemId;
+ uuid_set_t mItemList;
LLUUID mTaskId;
LLUUID mExpectingAssetId;
diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp
index 58604c5628..63802de6b3 100644
--- a/indra/newview/llfloatersimplesnapshot.cpp
+++ b/indra/newview/llfloatersimplesnapshot.cpp
@@ -50,7 +50,7 @@ const S32 LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN = 64;
static const std::string THUMBNAIL_UPLOAD_CAP = "InventoryThumbnailUpload";
-void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, LLSD first_data)
+void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, LLSD first_data, LLFloaterSimpleSnapshot::completion_t callback)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
@@ -129,6 +129,11 @@ void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, L
{
LL_WARNS("Thumbnail") << "Failed to upload image " << result << LL_ENDL;
}
+
+ if (callback)
+ {
+ callback(LLUUID());
+ }
return;
}
@@ -153,6 +158,11 @@ void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, L
// Are we supposed to get BulkUpdateInventory?
gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
}
+
+ if (callback)
+ {
+ callback(result["new_asset"].asUUID());
+ }
}
///----------------------------------------------------------------------------
@@ -364,7 +374,7 @@ void LLFloaterSimpleSnapshot::onSend()
std::string temp_file = gDirUtilp->getTempFilename();
if (previewp->createUploadFile(temp_file, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN))
{
- uploadImageUploadFile(temp_file, mInventoryId, mTaskId);
+ uploadImageUploadFile(temp_file, mInventoryId, mTaskId, mUploadCompletionCallback);
closeFloater();
}
else
@@ -372,6 +382,10 @@ void LLFloaterSimpleSnapshot::onSend()
LLSD notif_args;
notif_args["REASON"] = LLImage::getLastError().c_str();
LLNotificationsUtil::add("CannotUploadTexture", notif_args);
+ if (mUploadCompletionCallback)
+ {
+ mUploadCompletionCallback(LLUUID::null);
+ }
}
}
@@ -381,7 +395,10 @@ void LLFloaterSimpleSnapshot::postSave()
}
// static
-void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id)
+void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path,
+ const LLUUID &inventory_id,
+ const LLUUID &task_id,
+ completion_t callback)
{
// generate a temp texture file for coroutine
std::string temp_file = gDirUtilp->getTempFilename();
@@ -394,11 +411,14 @@ void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, cons
LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL;
return;
}
- uploadImageUploadFile(temp_file, inventory_id, task_id);
+ uploadImageUploadFile(temp_file, inventory_id, task_id, callback);
}
// static
-void LLFloaterSimpleSnapshot::uploadThumbnail(LLPointer<LLImageRaw> raw_image, const LLUUID& inventory_id, const LLUUID& task_id)
+void LLFloaterSimpleSnapshot::uploadThumbnail(LLPointer<LLImageRaw> raw_image,
+ const LLUUID& inventory_id,
+ const LLUUID& task_id,
+ completion_t callback)
{
std::string temp_file = gDirUtilp->getTempFilename();
if (!LLViewerTextureList::createUploadFile(raw_image, temp_file, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN))
@@ -409,11 +429,14 @@ void LLFloaterSimpleSnapshot::uploadThumbnail(LLPointer<LLImageRaw> raw_image, c
LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL;
return;
}
- uploadImageUploadFile(temp_file, inventory_id, task_id);
+ uploadImageUploadFile(temp_file, inventory_id, task_id, callback);
}
// static
-void LLFloaterSimpleSnapshot::uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id)
+void LLFloaterSimpleSnapshot::uploadImageUploadFile(const std::string &temp_file,
+ const LLUUID &inventory_id,
+ const LLUUID &task_id,
+ completion_t callback)
{
LLSD data;
@@ -442,7 +465,7 @@ void LLFloaterSimpleSnapshot::uploadImageUploadFile(const std::string &temp_file
}
LLCoros::instance().launch("postAgentUserImageCoro",
- boost::bind(post_thumbnail_image_coro, cap_url, temp_file, data));
+ boost::bind(post_thumbnail_image_coro, cap_url, temp_file, data, callback));
}
void LLFloaterSimpleSnapshot::update()
diff --git a/indra/newview/llfloatersimplesnapshot.h b/indra/newview/llfloatersimplesnapshot.h
index 91a81ee5c3..04a66daedb 100644
--- a/indra/newview/llfloatersimplesnapshot.h
+++ b/indra/newview/llfloatersimplesnapshot.h
@@ -62,8 +62,17 @@ public:
void setOwner(LLView *owner_view) { mOwner = owner_view; }
void postSave();
- static void uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id);
- static void uploadThumbnail(LLPointer<LLImageRaw> raw_image, const LLUUID& inventory_id, const LLUUID& task_id);
+
+ typedef boost::function<void(const LLUUID& asset_id)> completion_t;
+ void setComplectionCallback(completion_t callback) { mUploadCompletionCallback = callback; }
+ static void uploadThumbnail(const std::string &file_path,
+ const LLUUID &inventory_id,
+ const LLUUID &task_id,
+ completion_t callback = completion_t());
+ static void uploadThumbnail(LLPointer<LLImageRaw> raw_image,
+ const LLUUID& inventory_id,
+ const LLUUID& task_id,
+ completion_t callback = completion_t());
class Impl;
friend class Impl;
@@ -76,13 +85,17 @@ private:
void onCancel();
// uploads upload-ready file
- static void uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id);
+ static void uploadImageUploadFile(const std::string &temp_file,
+ const LLUUID &inventory_id,
+ const LLUUID &task_id,
+ completion_t callback);
LLUUID mInventoryId;
LLUUID mTaskId;
LLView* mOwner;
F32 mContextConeOpacity;
+ completion_t mUploadCompletionCallback;
};
///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 7056eeb496..0d393952c7 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -3264,6 +3264,23 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
ungroup_folder_items(*ids.begin());
}
}
+ else if ("thumbnail" == action)
+ {
+ if (selected_items.size() > 0)
+ {
+ LLSD data;
+ std::set<LLFolderViewItem*>::iterator set_iter;
+ for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+ {
+ LLFolderViewItem* folder_item = *set_iter;
+ if (!folder_item) continue;
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
+ if (!bridge) continue;
+ data.append(bridge->getUUID());
+ }
+ LLFloaterReg::showInstance("change_item_thumbnail", data);
+ }
+ }
else
{
std::set<LLFolderViewItem*>::iterator set_iter;
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp
index e966514955..27b6de611c 100644
--- a/indra/newview/llinventorygallerymenu.cpp
+++ b/indra/newview/llinventorygallerymenu.cpp
@@ -197,7 +197,11 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
}
else if ("thumbnail" == action)
{
- LLSD data(mUUIDs.front());
+ LLSD data;
+ for (const LLUUID& id : mUUIDs)
+ {
+ data.append(id);
+ }
LLFloaterReg::showInstance("change_item_thumbnail", data);
}
else if ("cut" == action)