diff options
-rw-r--r-- | indra/newview/llfloaterchangeitemthumbnail.cpp | 175 | ||||
-rw-r--r-- | indra/newview/llfloaterchangeitemthumbnail.h | 7 | ||||
-rw-r--r-- | indra/newview/llfloatersimplesnapshot.cpp | 39 | ||||
-rw-r--r-- | indra/newview/llfloatersimplesnapshot.h | 19 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 17 | ||||
-rw-r--r-- | indra/newview/llinventorygallerymenu.cpp | 6 |
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) |