From 6a260bb3f0bc5bf726ad1c3f98e39d3fb9679484 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Feb 2023 22:24:46 +0200 Subject: SL-19108 Rename outfit snapshot floater --- indra/newview/lloutfitgallery.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/lloutfitgallery.cpp') diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 602b7412a4..ce1330dfe1 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -41,7 +41,7 @@ #include "llfilepicker.h" #include "llfloaterperms.h" #include "llfloaterreg.h" -#include "llfloatersimpleoutfitsnapshot.h" +#include "llfloatersimplesnapshot.h" #include "llimagedimensionsinfo.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -1387,7 +1387,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id) void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) { LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot"); - LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance(); + LLFloaterSimpleSnapshot* snapshot_floater = LLFloaterSimpleSnapshot::getInstance(); if (snapshot_floater) { snapshot_floater->setOutfitID(selected_outfit_id); -- cgit v1.3 From 6786e43fcb315eb10b5ab4a205163fb424c18bc6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 21 Feb 2023 00:13:41 +0200 Subject: SL-19108 Managing inventory thumbnail --- indra/newview/llfloaterchangeitemthumbnail.cpp | 253 ++++++--------------- indra/newview/llfloaterchangeitemthumbnail.h | 4 +- indra/newview/llfloatersimplesnapshot.cpp | 155 ++++++++++++- indra/newview/llfloatersimplesnapshot.h | 3 + indra/newview/lloutfitgallery.cpp | 2 +- .../default/xui/en/floater_simple_snapshot.xml | 2 +- 6 files changed, 223 insertions(+), 196 deletions(-) (limited to 'indra/newview/lloutfitgallery.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index b267c7e0a3..4d76194b48 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -34,116 +34,23 @@ #include "llinventoryicon.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" +#include "llfloaterreg.h" +#include "llfloatersimplesnapshot.h" #include "lllineeditor.h" #include "lltextbox.h" #include "lltexturectrl.h" #include "llthumbnailctrl.h" +#include "llviewerfoldertype.h" #include "llviewermenufile.h" #include "llviewerobjectlist.h" #include "llwindow.h" -//TODO: this part is likely to be moved into outfit snapshot floater -// and flaoter is likely to become a thumbnail snapshot floater - -#include "llagent.h" -#include "llnotificationsutil.h" -#include "llviewertexturelist.h" - -static const std::string THUMBNAIL_ITEM_UPLOAD_CAP = "InventoryItemThumbnailUpload"; -static const std::string THUMBNAIL_CATEGORY_UPLOAD_CAP = "InventoryCategoryThumbnailUpload"; - -void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, LLSD first_data) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t httpHeaders; - - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - httpOpts->setFollowRedirects(true); - - LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - // todo: notification? - LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; - return; - } - if (!result.has("uploader")) - { - // todo: notification? - LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; - return; - } - std::string uploader_cap = result["uploader"].asString(); - if (uploader_cap.empty()) - { - LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; - return; - } - - // Upload the image - - LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); - LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); - S64 length; - - { - llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate); - if (!instream.is_open()) - { - LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; - return; - } - length = instream.tellg(); - } - - uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional - uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required! - uploaderhttpOpts->setFollowRedirects(true); - - result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders); - - httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - LL_DEBUGS("Thumbnail") << result << LL_ENDL; - - if (!status) - { - LL_WARNS("Thumbnail") << "Failed to upload image " << status.toString() << LL_ENDL; - return; - } - - if (result["state"].asString() != "complete") - { - if (result.has("message")) - { - LL_WARNS("Thumbnail") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL; - } - else - { - LL_WARNS("Thumbnail") << "Failed to upload image " << result << LL_ENDL; - } - return; - } - - // todo: issue an inventory udpate? - //return result["new_asset"].asUUID(); -} - class LLThumbnailImagePicker : public LLFilePickerThread { public: - LLThumbnailImagePicker(const LLUUID &item_id, LLHandle *handle); - LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id, LLHandle *handle); + LLThumbnailImagePicker(const LLUUID &item_id); + LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id); ~LLThumbnailImagePicker(); void notify(const std::vector& filenames) override; @@ -153,16 +60,14 @@ private: LLUUID mTaskId; }; -LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, LLHandle *handle) +LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id) : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE) - , mHandle(handle) , mInventoryId(item_id) { } -LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id, LLHandle *handle) +LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id) : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE) - , mHandle(handle) , mInventoryId(item_id) , mTaskId(task_id) { @@ -170,15 +75,10 @@ LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, const LLUU LLThumbnailImagePicker::~LLThumbnailImagePicker() { - delete mHandle; } void LLThumbnailImagePicker::notify(const std::vector& filenames) { - if (mHandle->isDead()) - { - return; - } if (filenames.empty()) { return; @@ -188,52 +88,8 @@ void LLThumbnailImagePicker::notify(const std::vector& filenames) { return; } - - // generate a temp texture file for coroutine - std::string temp_file = gDirUtilp->getTempFilename(); - U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); - const S32 MAX_DIM = 256; - if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) - { - LLSD notif_args; - notif_args["REASON"] = LLImage::getLastError().c_str(); - LLNotificationsUtil::add("CannotUploadTexture", notif_args); - LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << mInventoryId << " " << mTaskId << ", reason: " << notif_args["REASON"].asString() << LL_ENDL; - return; - } - - std::string cap_name; - LLSD data; - - if (mTaskId.notNull()) - { - cap_name = THUMBNAIL_ITEM_UPLOAD_CAP; - data["item_id"] = mInventoryId; - data["task_id"] = mTaskId; - } - else if (gInventory.getCategory(mInventoryId)) - { - cap_name = THUMBNAIL_CATEGORY_UPLOAD_CAP; - data["category_id"] = mInventoryId; - } - else - { - cap_name = THUMBNAIL_ITEM_UPLOAD_CAP; - data["item_id"] = mInventoryId; - } - - std::string cap_url = gAgent.getRegionCapability(cap_name); - if (cap_url.empty()) - { - LLSD args; - args["CAPABILITY"] = cap_url; - LLNotificationsUtil::add("RegionCapabilityRequestError", args); - LL_WARNS("Thumbnail") << "Failed to upload profile image for item " << mInventoryId << " " << mTaskId << ", no cap found" << LL_ENDL; - return; - } - - LLCoros::instance().launch("postAgentUserImageCoro", - boost::bind(post_thumbnail_image_coro, cap_url, temp_file, data)); + + LLFloaterSimpleSnapshot::uploadThumbnail(file_path, mInventoryId, mTaskId); } LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key) @@ -348,9 +204,9 @@ void LLFloaterChangeItemThumbnail::inventoryChanged(LLViewerObject* object, refreshFromInventory(); } -LLViewerInventoryItem* LLFloaterChangeItemThumbnail::getItem() +LLInventoryObject* LLFloaterChangeItemThumbnail::getInventoryObject() { - LLViewerInventoryItem* item = NULL; + LLInventoryObject* obj = NULL; if (mTaskId.isNull()) { // it is in agent inventory @@ -360,7 +216,7 @@ LLViewerInventoryItem* LLFloaterChangeItemThumbnail::getItem() mObserverInitialized = true; } - item = gInventory.getItem(mItemId); + obj = gInventory.getObject(mItemId); } else { @@ -373,28 +229,24 @@ LLViewerInventoryItem* LLFloaterChangeItemThumbnail::getItem() mObserverInitialized = false; } - item = static_cast(object->getInventoryObject(mItemId)); + obj = object->getInventoryObject(mItemId); } } - return item; + return obj; } void LLFloaterChangeItemThumbnail::refreshFromInventory() { - LLViewerInventoryItem* item = getItem(); - if (!item) + LLInventoryObject* obj = getInventoryObject(); + if (!obj) { closeFloater(); } - if (item) + if (obj) { - // This floater probably shouldn't be be possible to open - // for imcomplete items - llassert(item->isFinished()); - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - bool in_trash = (item->getUUID() == trash_id) || gInventory.isObjectDescendentOf(item->getUUID(), trash_id); + bool in_trash = (obj->getUUID() == trash_id) || gInventory.isObjectDescendentOf(obj->getUUID(), trash_id); if (in_trash) { // Close properties when moving to trash @@ -403,7 +255,7 @@ void LLFloaterChangeItemThumbnail::refreshFromInventory() } else { - refreshFromItem(item); + refreshFromObject(obj); } } else @@ -412,17 +264,37 @@ void LLFloaterChangeItemThumbnail::refreshFromInventory() } } -void LLFloaterChangeItemThumbnail::refreshFromItem(LLViewerInventoryItem* item) +void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) { - LLUIImagePtr icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE); + LLUIImagePtr icon_img; + LLUUID thumbnail_id = obj->getThumbnailUUID(); + + LLViewerInventoryItem* item = dynamic_cast(obj); + if (item) + { + // This floater probably shouldn't be be possible to open + // for imcomplete items + llassert(item->isFinished()); + + icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE); + mRemoveImageBtn->setEnabled(thumbnail_id.notNull() && ((item->getActualType() != LLAssetType::AT_TEXTURE) || (item->getAssetUUID() != thumbnail_id))); + } + else + { + LLViewerInventoryCategory* cat = dynamic_cast(obj); + + if (cat) + { + icon_img = LLUI::getUIImage(LLViewerFolderType::lookupIconName(cat->getPreferredType(), true)); + mRemoveImageBtn->setEnabled(thumbnail_id.notNull()); + } + } mItemTypeIcon->setImage(icon_img); - mItemNameText->setValue(item->getName()); + mItemNameText->setValue(obj->getName()); - LLUUID thumbnail_id = item->getThumbnailUUID(); mThumbnailCtrl->setValue(thumbnail_id); mCopyToClipboardBtn->setEnabled(thumbnail_id.notNull()); - mRemoveImageBtn->setEnabled(thumbnail_id.notNull() && ((item->getActualType() != LLAssetType::AT_TEXTURE) || (item->getAssetUUID() != thumbnail_id))); // todo: some elements might not support setting thumbnails // since they already have them @@ -431,7 +303,8 @@ void LLFloaterChangeItemThumbnail::refreshFromItem(LLViewerInventoryItem* item) void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata) { LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; - (new LLThumbnailImagePicker(self->mItemId, self->mTaskId, new LLHandle(self->getHandle())))->getFile(); + + (new LLThumbnailImagePicker(self->mItemId, self->mTaskId))->getFile(); LLFloater* floaterp = self->mPickerHandle.get(); if (floaterp) @@ -442,16 +315,24 @@ void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata) void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata) { + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + LLFloaterReg::toggleInstanceOrBringToFront("simple_snapshot"); + LLFloaterSimpleSnapshot* snapshot_floater = LLFloaterSimpleSnapshot::getInstance(); + if (snapshot_floater) + { + snapshot_floater->setInventoryId(self->mItemId); + snapshot_floater->setTaskId(self->mTaskId); + } } void LLFloaterChangeItemThumbnail::onUseTexture(void *userdata) { LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; - LLViewerInventoryItem* item = self->getItem(); - if (item) + LLInventoryObject* obj = self->getInventoryObject(); + if (obj) { - self->showTexturePicker(item->getThumbnailUUID()); + self->showTexturePicker(obj->getThumbnailUUID()); } } @@ -459,10 +340,10 @@ void LLFloaterChangeItemThumbnail::onUseTexture(void *userdata) void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) { LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; - LLViewerInventoryItem* item = self->getItem(); - if (item) + LLInventoryObject* obj = self->getInventoryObject(); + if (obj) { - LLClipboard::instance().addToClipboard(item->getThumbnailUUID()); + LLClipboard::instance().addToClipboard(obj->getThumbnailUUID()); } } @@ -473,10 +354,10 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) LLClipboard::instance().pasteFromClipboard(objects); if (objects.size() > 0) { - LLViewerInventoryItem* item = self->getItem(); - if (item) + LLInventoryObject* obj = self->getInventoryObject(); + if (obj) { - item->setThumbnailUUID(objects[0]); + obj->setThumbnailUUID(objects[0]); } } } @@ -484,7 +365,7 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) void LLFloaterChangeItemThumbnail::onRemove(void *userdata) { LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; - LLViewerInventoryItem* item = self->getItem(); + LLInventoryObject* item = self->getInventoryObject(); if (item) { item->setThumbnailUUID(LLUUID::null); @@ -548,11 +429,11 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) { LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mPickerHandle.get(); - LLViewerInventoryItem* item = getItem(); + LLInventoryObject* obj = getInventoryObject(); - if (item && floaterp) + if (obj && floaterp) { - item->setThumbnailUUID(floaterp->getAssetID()); + obj->setThumbnailUUID(floaterp->getAssetID()); } } diff --git a/indra/newview/llfloaterchangeitemthumbnail.h b/indra/newview/llfloaterchangeitemthumbnail.h index 340d5cf05e..b3ae0a18f6 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.h +++ b/indra/newview/llfloaterchangeitemthumbnail.h @@ -55,9 +55,9 @@ public: private: - LLViewerInventoryItem* getItem(); + LLInventoryObject* getInventoryObject(); void refreshFromInventory(); - void refreshFromItem(LLViewerInventoryItem* item); + void refreshFromObject(LLInventoryObject* obj); static void onUploadLocal(void*); static void onUploadSnapshot(void*); diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp index 05625e6817..ca2b9b919a 100644 --- a/indra/newview/llfloatersimplesnapshot.cpp +++ b/indra/newview/llfloatersimplesnapshot.cpp @@ -33,16 +33,110 @@ #include "llstatusbar.h" // can_afford_transaction() #include "llnotificationsutil.h" #include "lloutfitgallery.h" +#include "llagent.h" #include "llagentbenefits.h" #include "llviewercontrol.h" +#include "llviewertexturelist.h" + + LLSimpleSnapshotFloaterView* gSimpleSnapshotFloaterView = NULL; -const S32 THUMBNAIL_SNAPSHOT_WIDTH = 256; -const S32 THUMBNAIL_SNAPSHOT_HEIGHT = 256; +const S32 THUMBNAIL_SNAPSHOT_DIM = 256; static LLDefaultChildRegistry::Register r("simple_snapshot_floater_view"); +// Thumbnail posting coro + +static const std::string THUMBNAIL_ITEM_UPLOAD_CAP = "InventoryItemThumbnailUpload"; +static const std::string THUMBNAIL_CATEGORY_UPLOAD_CAP = "InventoryCategoryThumbnailUpload"; + +void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, LLSD first_data) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + // todo: notification? + LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; + return; + } + if (!result.has("uploader")) + { + // todo: notification? + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; + return; + } + std::string uploader_cap = result["uploader"].asString(); + if (uploader_cap.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; + return; + } + + // Upload the image + + LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); + LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); + S64 length; + + { + llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate); + if (!instream.is_open()) + { + LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; + return; + } + length = instream.tellg(); + } + + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required! + uploaderhttpOpts->setFollowRedirects(true); + + result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders); + + httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LL_DEBUGS("Thumbnail") << result << LL_ENDL; + + if (!status) + { + LL_WARNS("Thumbnail") << "Failed to upload image " << status.toString() << LL_ENDL; + return; + } + + if (result["state"].asString() != "complete") + { + if (result.has("message")) + { + LL_WARNS("Thumbnail") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL; + } + else + { + LL_WARNS("Thumbnail") << "Failed to upload image " << result << LL_ENDL; + } + return; + } + + // todo: issue an inventory udpate? + //return result["new_asset"].asUUID(); +} + ///---------------------------------------------------------------------------- /// Class LLFloaterSimpleSnapshot::Impl ///---------------------------------------------------------------------------- @@ -84,8 +178,8 @@ void LLFloaterSimpleSnapshot::Impl::updateResolution(void* data) return; } - S32 width = THUMBNAIL_SNAPSHOT_WIDTH; - S32 height = THUMBNAIL_SNAPSHOT_HEIGHT; + S32 width = THUMBNAIL_SNAPSHOT_DIM; + S32 height = THUMBNAIL_SNAPSHOT_DIM; LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) @@ -263,6 +357,55 @@ void LLFloaterSimpleSnapshot::postSave() impl->setStatus(ImplBase::STATUS_WORKING); } +// static +void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id) +{ + // generate a temp texture file for coroutine + std::string temp_file = gDirUtilp->getTempFilename(); + U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); + if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, THUMBNAIL_SNAPSHOT_DIM)) + { + LLSD notif_args; + notif_args["REASON"] = LLImage::getLastError().c_str(); + LLNotificationsUtil::add("CannotUploadTexture", notif_args); + LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL; + return; + } + + std::string cap_name; + LLSD data; + + if (task_id.notNull()) + { + cap_name = THUMBNAIL_ITEM_UPLOAD_CAP; + data["item_id"] = inventory_id; + data["task_id"] = task_id; + } + else if (gInventory.getCategory(inventory_id)) + { + cap_name = THUMBNAIL_CATEGORY_UPLOAD_CAP; + data["category_id"] = inventory_id; + } + else + { + cap_name = THUMBNAIL_ITEM_UPLOAD_CAP; + data["item_id"] = inventory_id; + } + + std::string cap_url = gAgent.getRegionCapability(cap_name); + if (cap_url.empty()) + { + LLSD args; + args["CAPABILITY"] = cap_url; + LLNotificationsUtil::add("RegionCapabilityRequestError", args); + LL_WARNS("Thumbnail") << "Failed to upload profile image for item " << inventory_id << " " << task_id << ", no cap found" << LL_ENDL; + return; + } + + LLCoros::instance().launch("postAgentUserImageCoro", + boost::bind(post_thumbnail_image_coro, cap_url, temp_file, data)); +} + // static void LLFloaterSimpleSnapshot::update() { @@ -277,13 +420,13 @@ void LLFloaterSimpleSnapshot::update() // static LLFloaterSimpleSnapshot* LLFloaterSimpleSnapshot::findInstance() { - return LLFloaterReg::findTypedInstance("simple_outfit_snapshot"); + return LLFloaterReg::findTypedInstance("simple_snapshot"); } // static LLFloaterSimpleSnapshot* LLFloaterSimpleSnapshot::getInstance() { - return LLFloaterReg::getTypedInstance("simple_outfit_snapshot"); + return LLFloaterReg::getTypedInstance("simple_snapshot"); } void LLFloaterSimpleSnapshot::saveTexture() diff --git a/indra/newview/llfloatersimplesnapshot.h b/indra/newview/llfloatersimplesnapshot.h index f9a1d9b9bf..55253b38e8 100644 --- a/indra/newview/llfloatersimplesnapshot.h +++ b/indra/newview/llfloatersimplesnapshot.h @@ -61,8 +61,11 @@ public: void setOutfitID(LLUUID id) { mOutfitID = id; } LLUUID getOutfitID() { return mOutfitID; } void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } + void setInventoryId(const LLUUID &inventory_id) {} + void setTaskId(const LLUUID &task_id) {} void postSave(); + static void uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id); class Impl; friend class Impl; diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index ce1330dfe1..06dbf50bee 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1386,7 +1386,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id) void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) { - LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot"); + LLFloaterReg::toggleInstanceOrBringToFront("simple_snapshot"); LLFloaterSimpleSnapshot* snapshot_floater = LLFloaterSimpleSnapshot::getInstance(); if (snapshot_floater) { diff --git a/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml b/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml index 1e47a3b35d..a53d42be2e 100644 --- a/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml @@ -12,7 +12,7 @@ help_topic="snapshot" save_rect="true" save_visibility="false" - title="OUTFIT SNAPSHOT" + title="THUMBNAIL SNAPSHOT" width="351"> Date: Tue, 21 Feb 2023 23:03:00 +0200 Subject: SL-19108 Update Simple snapshot floater --- indra/newview/llfloaterchangeitemthumbnail.cpp | 47 ++++++++++++++++++++++ indra/newview/llfloatersimplesnapshot.cpp | 42 ++++++++----------- indra/newview/llfloatersimplesnapshot.h | 17 ++++---- indra/newview/llinspecttexture.cpp | 3 +- indra/newview/lloutfitgallery.cpp | 40 +++--------------- indra/newview/lloutfitgallery.h | 5 +-- indra/newview/lloutfitslist.cpp | 27 +++---------- indra/newview/lloutfitslist.h | 5 +-- indra/newview/llsnapshotlivepreview.cpp | 26 ++++++++++++ indra/newview/llsnapshotlivepreview.h | 1 + .../default/xui/en/floater_simple_snapshot.xml | 4 +- .../default/xui/en/menu_gallery_outfit_tab.xml | 32 ++------------- .../skins/default/xui/en/menu_outfit_gear.xml | 6 +-- 13 files changed, 123 insertions(+), 132 deletions(-) (limited to 'indra/newview/lloutfitgallery.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 378f5bc132..5b47c483fb 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -31,6 +31,7 @@ #include "llbutton.h" #include "llclipboard.h" #include "lliconctrl.h" +#include "llinventoryfunctions.h" #include "llinventoryicon.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" @@ -264,6 +265,20 @@ void LLFloaterChangeItemThumbnail::refreshFromInventory() } } +class LLIsOutfitTextureType : public LLInventoryCollectFunctor +{ +public: + LLIsOutfitTextureType() {} + virtual ~LLIsOutfitTextureType() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +}; + +bool LLIsOutfitTextureType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + return item && (item->getType() == LLAssetType::AT_TEXTURE); +} + void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) { LLUIImagePtr icon_img; @@ -286,6 +301,35 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) if (cat) { icon_img = LLUI::getUIImage(LLViewerFolderType::lookupIconName(cat->getPreferredType(), true)); + + if (thumbnail_id.isNull() && (cat->getPreferredType() == LLFolderType::FT_OUTFIT)) + { + // Legacy support, check if there is an image inside + + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + // Not LLIsOfAssetType, because we allow links + LLIsOutfitTextureType f; + gInventory.getDirectDescendentsOf(mItemId, cats, items, f); + + if (1 == items.size()) + { + LLViewerInventoryItem* item = items.front(); + if (item && item->getIsLinkType()) + { + item = item->getLinkedItem(); + } + if (item) + { + thumbnail_id = item->getAssetUUID(); + + // per SL-19188, set this image as a thumbnail + cat->setThumbnailUUID(thumbnail_id); + // todo: needs to trigger send/update once server support is done + } + } + } + mRemoveImageBtn->setEnabled(thumbnail_id.notNull()); } } @@ -358,6 +402,7 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) if (obj) { obj->setThumbnailUUID(objects[0]); + // todo: need to trigger send/update once server support is done } } } @@ -384,6 +429,7 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio if (obj) { obj->setThumbnailUUID(LLUUID::null); + // todo: need to trigger send/update once server support is done } } } @@ -450,6 +496,7 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) if (obj && floaterp) { obj->setThumbnailUUID(floaterp->getAssetID()); + // todo: need to trigger send/update once server support is done } } diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp index ca2b9b919a..096db132ac 100644 --- a/indra/newview/llfloatersimplesnapshot.cpp +++ b/indra/newview/llfloatersimplesnapshot.cpp @@ -30,9 +30,9 @@ #include "llfloaterreg.h" #include "llimagefiltersmanager.h" +#include "llinventorymodel.h" #include "llstatusbar.h" // can_afford_transaction() #include "llnotificationsutil.h" -#include "lloutfitgallery.h" #include "llagent.h" #include "llagentbenefits.h" #include "llviewercontrol.h" @@ -44,8 +44,6 @@ LLSimpleSnapshotFloaterView* gSimpleSnapshotFloaterView = NULL; const S32 THUMBNAIL_SNAPSHOT_DIM = 256; -static LLDefaultChildRegistry::Register r("simple_snapshot_floater_view"); - // Thumbnail posting coro static const std::string THUMBNAIL_ITEM_UPLOAD_CAP = "InventoryItemThumbnailUpload"; @@ -229,8 +227,7 @@ void LLFloaterSimpleSnapshot::Impl::setStatus(EStatus status, bool ok, const std ///---------------------------------------------------------------------------- LLFloaterSimpleSnapshot::LLFloaterSimpleSnapshot(const LLSD& key) - : LLFloaterSnapshotBase(key), - mOutfitGallery(NULL) + : LLFloaterSnapshotBase(key) { impl = new Impl(this); } @@ -241,8 +238,6 @@ LLFloaterSimpleSnapshot::~LLFloaterSimpleSnapshot() BOOL LLFloaterSimpleSnapshot::postBuild() { - getChild("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); - childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); childSetAction("save_btn", boost::bind(&LLFloaterSimpleSnapshot::onSend, this)); childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleSnapshot::onCancel, this)); @@ -337,18 +332,18 @@ void LLFloaterSimpleSnapshot::onCancel() void LLFloaterSimpleSnapshot::onSend() { - S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - if (can_afford_transaction(expected_upload_cost)) + LLSnapshotLivePreview* previewp = getPreviewView(); + + std::string temp_file = gDirUtilp->getTempFilename(); + if (previewp->createUploadFile(temp_file, THUMBNAIL_SNAPSHOT_DIM)) { - saveTexture(); - postSave(); + uploadImageUploadFile(temp_file, mInventoryId, mTaskId); } else { - LLSD args; - args["COST"] = llformat("%d", expected_upload_cost); - LLNotificationsUtil::add("ErrorPhotoCannotAfford", args); - inventorySaveFailed(); + LLSD notif_args; + notif_args["REASON"] = LLImage::getLastError().c_str(); + LLNotificationsUtil::add("CannotUploadTexture", notif_args); } } @@ -371,7 +366,12 @@ 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); +} +// static +void LLFloaterSimpleSnapshot::uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id) +{ std::string cap_name; LLSD data; @@ -431,22 +431,14 @@ LLFloaterSimpleSnapshot* LLFloaterSimpleSnapshot::getInstance() void LLFloaterSimpleSnapshot::saveTexture() { - LLSnapshotLivePreview* previewp = getPreviewView(); + LLSnapshotLivePreview* previewp = getPreviewView(); if (!previewp) { llassert(previewp != NULL); return; } - if (mOutfitGallery) - { - mOutfitGallery->onBeforeOutfitSnapshotSave(); - } - previewp->saveTexture(TRUE, getOutfitID().asString()); - if (mOutfitGallery) - { - mOutfitGallery->onAfterOutfitSnapshotSave(); - } + previewp->saveTexture(TRUE, getInventoryId().asString()); closeFloater(); } diff --git a/indra/newview/llfloatersimplesnapshot.h b/indra/newview/llfloatersimplesnapshot.h index 55253b38e8..59cb526704 100644 --- a/indra/newview/llfloatersimplesnapshot.h +++ b/indra/newview/llfloatersimplesnapshot.h @@ -31,8 +31,6 @@ #include "llfloatersnapshot.h" #include "llsnapshotlivepreview.h" -class LLOutfitGallery; - ///---------------------------------------------------------------------------- /// Class LLFloaterSimpleSnapshot ///---------------------------------------------------------------------------- @@ -58,11 +56,9 @@ public: const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - void setOutfitID(LLUUID id) { mOutfitID = id; } - LLUUID getOutfitID() { return mOutfitID; } - void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } - void setInventoryId(const LLUUID &inventory_id) {} - void setTaskId(const LLUUID &task_id) {} + void setInventoryId(const LLUUID &inventory_id) { mInventoryId = inventory_id; } + LLUUID getInventoryId() { return mInventoryId; } + void setTaskId(const LLUUID &task_id) { mTaskId = task_id; } void postSave(); static void uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id); @@ -74,8 +70,11 @@ private: void onSend(); void onCancel(); - LLUUID mOutfitID; - LLOutfitGallery* mOutfitGallery; + // uploads upload-ready file + static void uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id); + + LLUUID mInventoryId; + LLUUID mTaskId; }; ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinspecttexture.cpp b/indra/newview/llinspecttexture.cpp index de0d65eb7e..2e8273d6cf 100644 --- a/indra/newview/llinspecttexture.cpp +++ b/indra/newview/llinspecttexture.cpp @@ -185,7 +185,8 @@ LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p) } if (item) { - // Todo: write this into folder's thumbnail id + // Note: LLFloaterChangeItemThumbnail will attempt to write this + // into folder's thumbnail id when opened p.create_params.getValue()["thumbnail_id"] = item->getAssetUUID(); return LLUICtrlFactory::create(p); } diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 06dbf50bee..d30cc66a38 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -837,52 +837,23 @@ LLContextMenu* LLOutfitGalleryContextMenu::createMenu() registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); registrar.add("Outfit.Delete", boost::bind(&LLOutfitGalleryContextMenu::onRemoveOutfit, this, selected_id)); registrar.add("Outfit.Create", boost::bind(&LLOutfitGalleryContextMenu::onCreate, this, _2)); - registrar.add("Outfit.UploadPhoto", boost::bind(&LLOutfitGalleryContextMenu::onUploadPhoto, this, selected_id)); - registrar.add("Outfit.SelectPhoto", boost::bind(&LLOutfitGalleryContextMenu::onSelectPhoto, this, selected_id)); - registrar.add("Outfit.TakeSnapshot", boost::bind(&LLOutfitGalleryContextMenu::onTakeSnapshot, this, selected_id)); - registrar.add("Outfit.RemovePhoto", boost::bind(&LLOutfitGalleryContextMenu::onRemovePhoto, this, selected_id)); + registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitGalleryContextMenu::onThumbnail, this, selected_id)); enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2)); enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2)); return createFromFile("menu_gallery_outfit_tab.xml"); } -void LLOutfitGalleryContextMenu::onUploadPhoto(const LLUUID& outfit_cat_id) +void LLOutfitGalleryContextMenu::onThumbnail(const LLUUID& outfit_cat_id) { LLOutfitGallery* gallery = dynamic_cast(mOutfitList); if (gallery && outfit_cat_id.notNull()) { - gallery->uploadPhoto(outfit_cat_id); + LLSD data(outfit_cat_id); + LLFloaterReg::showInstance("change_item_thumbnail", data); } } -void LLOutfitGalleryContextMenu::onSelectPhoto(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->onSelectPhoto(outfit_cat_id); - } -} - -void LLOutfitGalleryContextMenu::onRemovePhoto(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->checkRemovePhoto(outfit_cat_id); - gallery->refreshOutfit(outfit_cat_id); - } -} - -void LLOutfitGalleryContextMenu::onTakeSnapshot(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->onTakeSnapshot(outfit_cat_id); - } -} void LLOutfitGalleryContextMenu::onRemoveOutfit(const LLUUID& outfit_cat_id) { @@ -1390,8 +1361,7 @@ void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) LLFloaterSimpleSnapshot* snapshot_floater = LLFloaterSimpleSnapshot::getInstance(); if (snapshot_floater) { - snapshot_floater->setOutfitID(selected_outfit_id); - snapshot_floater->getInstance()->setGallery(this); + snapshot_floater->setInventoryId(selected_outfit_id); } } diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h index ce5c090134..4839477cb2 100644 --- a/indra/newview/lloutfitgallery.h +++ b/indra/newview/lloutfitgallery.h @@ -215,10 +215,7 @@ protected: /* virtual */ LLContextMenu* createMenu(); bool onEnable(LLSD::String param); bool onVisible(LLSD::String param); - void onUploadPhoto(const LLUUID& outfit_cat_id); - void onSelectPhoto(const LLUUID& outfit_cat_id); - void onRemovePhoto(const LLUUID& outfit_cat_id); - void onTakeSnapshot(const LLUUID& outfit_cat_id); + void onThumbnail(const LLUUID& outfit_cat_id); void onCreate(const LLSD& data); void onRemoveOutfit(const LLUUID& outfit_cat_id); void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response, const LLUUID& outfit_cat_id); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 4171fd8822..2f7d1c433a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -36,6 +36,7 @@ #include "llagentwearables.h" #include "llappearancemgr.h" #include "llagentbenefits.h" +#include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -1112,10 +1113,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist) registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this)); - registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this)); - registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this)); - registrar.add("Gear.TakeSnapshot", boost::bind(&LLOutfitListGearMenuBase::onTakeSnapshot, this)); - registrar.add("Gear.RemovePhoto", boost::bind(&LLOutfitListGearMenuBase::onRemovePhoto, this)); + registrar.add("Gear.Thumbnail", boost::bind(&LLOutfitListGearMenuBase::onThumbnail, this)); registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this)); enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2)); @@ -1251,24 +1249,11 @@ bool LLOutfitListGearMenuBase::onVisible(LLSD::String param) return true; } -void LLOutfitListGearMenuBase::onUploadFoto() +void LLOutfitListGearMenuBase::onThumbnail() { - -} - -void LLOutfitListGearMenuBase::onSelectPhoto() -{ - -} - -void LLOutfitListGearMenuBase::onTakeSnapshot() -{ - -} - -void LLOutfitListGearMenuBase::onRemovePhoto() -{ - + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + LLSD data(selected_outfit_id); + LLFloaterReg::showInstance("change_item_thumbnail", data); } void LLOutfitListGearMenuBase::onChangeSortOrder() diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 81be8de94f..66b3165169 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -163,10 +163,7 @@ public: protected: virtual void onUpdateItemsVisibility(); - virtual void onUploadFoto(); - virtual void onSelectPhoto(); - virtual void onTakeSnapshot(); - virtual void onRemovePhoto(); + virtual void onThumbnail(); virtual void onChangeSortOrder(); const LLUUID& getSelectedOutfitID(); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index ed7e18fadc..273e3a403d 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -51,6 +51,7 @@ #include "llviewercontrol.h" #include "llviewermenufile.h" // upload_new_resource() #include "llviewerstats.h" +#include "llviewertexturelist.h" #include "llwindow.h" #include "llworld.h" #include @@ -873,6 +874,31 @@ LLPointer LLSnapshotLivePreview::getEncodedImage() return mPreviewImageEncoded; } +bool LLSnapshotLivePreview::createUploadFile(const std::string &out_filename, const S32 max_image_dimentions) +{ + // make a copy, since convertToUploadFile modifies raw image + LLPointer raw_image = new LLImageRaw( + mPreviewImage->getData(), + mPreviewImage->getWidth(), + mPreviewImage->getHeight(), + mPreviewImage->getComponents()); + + LLPointer compressedImage = LLViewerTextureList::convertToUploadFile(raw_image, max_image_dimentions); + if (compressedImage.isNull()) + { + compressedImage->setLastError("Couldn't convert the image to jpeg2000."); + LL_INFOS() << "Couldn't convert to j2c, file : " << out_filename << LL_ENDL; + return false; + } + if (!compressedImage->save(out_filename)) + { + compressedImage->setLastError("Couldn't create the jpeg2000 image for upload."); + LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL; + return false; + } + return true; +} + // We actually estimate the data size so that we do not require actual compression when showing the preview // Note : whenever formatted image is computed, mDataSize will be updated to reflect the true size void LLSnapshotLivePreview::estimateDataSize() diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index 1f81307976..e78c885789 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -106,6 +106,7 @@ public: LLPointer getFormattedImage(); LLPointer getEncodedImage(); + bool createUploadFile(const std::string &out_file, const S32 max_image_dimentions); /// Sets size of preview thumbnail image and the surrounding rect. void setThumbnailPlaceholderRect(const LLRect& rect) {mThumbnailPlaceholderRect = rect; } diff --git a/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml b/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml index a53d42be2e..97ea59593e 100644 --- a/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml @@ -12,7 +12,7 @@ help_topic="snapshot" save_rect="true" save_visibility="false" - title="THUMBNAIL SNAPSHOT" + title="ITEM SNAPSHOT" width="351">