From ec02220f068c7e7ec61e8c8af7a3c4c96c112172 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 15 Feb 2023 02:19:49 +0200 Subject: SL-19108 WIP Managing inventory thumbnail #1 --- indra/newview/llfloaterchangeitemthumbnail.cpp | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 indra/newview/llfloaterchangeitemthumbnail.cpp (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp new file mode 100644 index 0000000000..7590fc35d1 --- /dev/null +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -0,0 +1,41 @@ +/** + * @file llfloaterchangeitemthumbnail.cpp + * @brief LLFloaterChangeItemThumbnail class implementation + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterchangeitemthumbnail.h" + +#include "lllineeditor.h" + + +LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key) + : LLPreview(key) +{ +} + +LLFloaterChangeItemThumbnail::~LLFloaterChangeItemThumbnail() +{ +} -- cgit v1.2.3 From f2d46651b92d949a63d2b3a5dd774dce6a6752c7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 15 Feb 2023 23:56:49 +0200 Subject: SL-19108 WIP Managing inventory thumbnail #2 --- indra/newview/llfloaterchangeitemthumbnail.cpp | 249 ++++++++++++++++++++++++- 1 file changed, 248 insertions(+), 1 deletion(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 7590fc35d1..05b9b89dd3 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -28,14 +28,261 @@ #include "llfloaterchangeitemthumbnail.h" +#include "llbutton.h" +#include "lliconctrl.h" +#include "llinventoryicon.h" +#include "llinventorymodel.h" +#include "llinventoryobserver.h" #include "lllineeditor.h" +#include "lltextbox.h" +#include "llthumbnailctrl.h" +#include "llviewerobjectlist.h" LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key) - : LLPreview(key) + : LLFloater(key) + , mObserverInitialized(false) + , mTooltipState(TOOLTIP_NONE) { } LLFloaterChangeItemThumbnail::~LLFloaterChangeItemThumbnail() { + gInventory.removeObserver(this); + removeVOInventoryListener(); } + +BOOL LLFloaterChangeItemThumbnail::postBuild() +{ + mItemNameText = getChild("item_name"); + mItemTypeIcon = getChild("item_type_icon"); + mThumbnailCtrl = getChild("item_thumbnail"); + mToolTipTextBox = getChild("tooltip_text"); + + LLSD tooltip_text; + mToolTipTextBox->setValue(tooltip_text); + + LLButton *upload_local = getChild("upload_local"); + upload_local->setClickedCallback(onUploadLocal, (void*)this); + upload_local->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_UPLOAD_LOCAL)); + upload_local->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_UPLOAD_LOCAL)); + + LLButton *upload_snapshot = getChild("upload_snapshot"); + upload_snapshot->setClickedCallback(onUploadSnapshot, (void*)this); + upload_snapshot->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_UPLOAD_SNAPSHOT)); + upload_snapshot->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_UPLOAD_SNAPSHOT)); + + LLButton *use_texture = getChild("use_texture"); + use_texture->setClickedCallback(onUseTexture, (void*)this); + use_texture->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_USE_TEXTURE)); + use_texture->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_USE_TEXTURE)); + + mCopyToClipboardBtn = getChild("copy_to_clipboard"); + mCopyToClipboardBtn->setClickedCallback(onCopyToClipboard, (void*)this); + mCopyToClipboardBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_COPY_TO_CLIPBOARD)); + mCopyToClipboardBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_COPY_TO_CLIPBOARD)); + + mPasteFromClipboardBtn = getChild("paste_from_clipboard"); + mPasteFromClipboardBtn->setClickedCallback(onPasteFromClipboard, (void*)this); + mPasteFromClipboardBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_COPY_FROM_CLIPBOARD)); + mPasteFromClipboardBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_COPY_FROM_CLIPBOARD)); + + mRemoveImageBtn = getChild("remove_image"); + mRemoveImageBtn->setClickedCallback(onRemove, (void*)this); + mRemoveImageBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_REMOVE)); + mRemoveImageBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_REMOVE)); + + return LLFloater::postBuild(); +} + +void LLFloaterChangeItemThumbnail::onOpen(const LLSD& key) +{ + if (!key.has("item_id") && !key.isUUID()) + { + closeFloater(); + } + + if (key.isUUID()) + { + mItemId = key.asUUID(); + } + else + { + mItemId = key["item_id"].asUUID(); + mTaskId = key["task_id"].asUUID(); + } + + refreshFromInventory(); +} + +void LLFloaterChangeItemThumbnail::changed(U32 mask) +{ + //LLInventoryObserver + + if (mTaskId.notNull() || mItemId.isNull()) + { + // Task inventory or not set up yet + return; + } + + const std::set& mChangedItemIDs = gInventory.getChangedIDs(); + std::set::const_iterator it; + + 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) + { + // if there's a change we're interested in. + if ((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0) + { + refreshFromInventory(); + } + } + } +} + +void LLFloaterChangeItemThumbnail::inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) +{ + //LLVOInventoryListener + refreshFromInventory(); +} + +void LLFloaterChangeItemThumbnail::refreshFromInventory() +{ + LLViewerInventoryItem* item = NULL; + if (mTaskId.isNull()) + { + // it is in agent inventory + if (!mObserverInitialized) + { + gInventory.addObserver(this); + mObserverInitialized = true; + } + + item = gInventory.getItem(mItemId); + } + else + { + LLViewerObject* object = gObjectList.findObject(mTaskId); + if (object) + { + if (!mObserverInitialized) + { + registerVOInventoryListener(object, NULL); + mObserverInitialized = false; + } + + item = static_cast(object->getInventoryObject(mItemId)); + } + else + { + closeFloater(); + } + } + + if (item) + { + // 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); + if (in_trash) + { + // Close properties when moving to trash + // Aren't supposed to view properties from trash + closeFloater(); + } + else + { + refreshFromItem(item); + } + } + else + { + closeFloater(); + } +} + +void LLFloaterChangeItemThumbnail::refreshFromItem(LLViewerInventoryItem* item) +{ + LLUIImagePtr icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE); + mItemTypeIcon->setImage(icon_img); + mItemNameText->setValue(item->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)); +} + +void LLFloaterChangeItemThumbnail::startObjectInventoryObserver() +{ + +} + +void LLFloaterChangeItemThumbnail::stopObjectInventoryObserver() +{ + +} + +void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onUseTexture(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onRemove(void *userdata) +{ + +} + +void LLFloaterChangeItemThumbnail::onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state) +{ + mTooltipState = state; + + std::string tooltip_text; + std::string tooltip_name = "tooltip_" + button->getName(); + if (hasString(tooltip_name)) + { + tooltip_text = getString(tooltip_name); + } + + mToolTipTextBox->setValue(tooltip_text); +} + +void LLFloaterChangeItemThumbnail::onButtonMouseLeave(LLUICtrl* button, const LLSD& param, EToolTipState state) +{ + if (mTooltipState == state) + { + mTooltipState = TOOLTIP_NONE; + LLSD tooltip_text; + mToolTipTextBox->setValue(tooltip_text); + } +} + -- cgit v1.2.3 From 8fdd6849995748b144b811d2e9585aeb2c56562d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 17 Feb 2023 18:54:50 +0200 Subject: SL-19108 WIP Managing inventory thumbnail #3 --- indra/newview/llfloaterchangeitemthumbnail.cpp | 125 +++++++++++++++++++++---- 1 file changed, 109 insertions(+), 16 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 05b9b89dd3..90fecd07ba 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -29,14 +29,17 @@ #include "llfloaterchangeitemthumbnail.h" #include "llbutton.h" +#include "llclipboard.h" #include "lliconctrl.h" #include "llinventoryicon.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "lllineeditor.h" #include "lltextbox.h" +#include "lltexturectrl.h" #include "llthumbnailctrl.h" #include "llviewerobjectlist.h" +#include "llwindow.h" LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key) @@ -151,7 +154,7 @@ void LLFloaterChangeItemThumbnail::inventoryChanged(LLViewerObject* object, refreshFromInventory(); } -void LLFloaterChangeItemThumbnail::refreshFromInventory() +LLViewerInventoryItem* LLFloaterChangeItemThumbnail::getItem() { LLViewerInventoryItem* item = NULL; if (mTaskId.isNull()) @@ -178,10 +181,16 @@ void LLFloaterChangeItemThumbnail::refreshFromInventory() item = static_cast(object->getInventoryObject(mItemId)); } - else - { - closeFloater(); - } + } + return item; +} + +void LLFloaterChangeItemThumbnail::refreshFromInventory() +{ + LLViewerInventoryItem* item = getItem(); + if (!item) + { + closeFloater(); } if (item) @@ -220,16 +229,9 @@ void LLFloaterChangeItemThumbnail::refreshFromItem(LLViewerInventoryItem* item) mCopyToClipboardBtn->setEnabled(thumbnail_id.notNull()); mRemoveImageBtn->setEnabled(thumbnail_id.notNull() && (item->getActualType() != LLAssetType::AT_TEXTURE) || (item->getAssetUUID() != thumbnail_id)); -} - -void LLFloaterChangeItemThumbnail::startObjectInventoryObserver() -{ - -} - -void LLFloaterChangeItemThumbnail::stopObjectInventoryObserver() -{ + // todo: some elements might not support setting thumbnails + // since they already have them } void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata) @@ -244,22 +246,113 @@ void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata) void LLFloaterChangeItemThumbnail::onUseTexture(void *userdata) { + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + LLViewerInventoryItem* item = self->getItem(); + if (item) + { + self->showTexturePicker(item->getThumbnailUUID()); + } } void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) { - + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + LLViewerInventoryItem* item = self->getItem(); + if (item) + { + LLClipboard::instance().addToClipboard(item->getThumbnailUUID()); + } } void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) { - + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + std::vector objects; + LLClipboard::instance().pasteFromClipboard(objects); + if (objects.size() > 0) + { + LLViewerInventoryItem* item = self->getItem(); + if (item) + { + item->setThumbnailUUID(objects[0]); + } + } } void LLFloaterChangeItemThumbnail::onRemove(void *userdata) { + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + LLViewerInventoryItem* item = self->getItem(); + if (item) + { + item->setThumbnailUUID(LLUUID::null); + } +} + +void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) +{ + // show hourglass cursor when loading inventory window + getWindow()->setCursor(UI_CURSOR_WAIT); + LLFloater* floaterp = mPickerHandle.get(); + // Show the dialog + if (floaterp) + { + floaterp->openFloater(); + } + else + { + floaterp = new LLFloaterTexturePicker( + this, + thumbnail_id, + thumbnail_id, + thumbnail_id, + FALSE, + TRUE, + "SELECT PHOTO", + PERM_NONE, + PERM_NONE, + PERM_NONE, + FALSE, + NULL); + + mPickerHandle = floaterp->getHandle(); + + LLFloaterTexturePicker* texture_floaterp = dynamic_cast(floaterp); + if (texture_floaterp) + { + //texture_floaterp->setTextureSelectedCallback(); + //texture_floaterp->setOnUpdateImageStatsCallback(); + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) + { + if (op == LLTextureCtrl::TEXTURE_SELECT) + { + onTexturePickerCommit(id); + } + } + ); + + texture_floaterp->setLocalTextureEnabled(FALSE); + texture_floaterp->setBakeTextureEnabled(FALSE); + texture_floaterp->setCanApplyImmediately(false); + texture_floaterp->setCanApply(false, true); + } + + floaterp->openFloater(); + } + floaterp->setFocus(TRUE); +} + +void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) +{ + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mPickerHandle.get(); + LLViewerInventoryItem* item = getItem(); + + if (item && floaterp) + { + item->setThumbnailUUID(floaterp->getAssetID()); + } } void LLFloaterChangeItemThumbnail::onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state) -- cgit v1.2.3 From e45dce1b75bd04459d5e6839bee8bf8b93dd0a5b Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Mon, 20 Feb 2023 18:37:18 +0200 Subject: mac build fix --- indra/newview/llfloaterchangeitemthumbnail.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 90fecd07ba..bd528f43dc 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -228,7 +228,7 @@ void LLFloaterChangeItemThumbnail::refreshFromItem(LLViewerInventoryItem* item) mThumbnailCtrl->setValue(thumbnail_id); mCopyToClipboardBtn->setEnabled(thumbnail_id.notNull()); - mRemoveImageBtn->setEnabled(thumbnail_id.notNull() && (item->getActualType() != LLAssetType::AT_TEXTURE) || (item->getAssetUUID() != thumbnail_id)); + 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 -- cgit v1.2.3 From e40f9af831c1257dea37a4565aafd73baa5005b6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Feb 2023 22:06:15 +0200 Subject: SL-19108 WIP Managing inventory thumbnail #5 --- indra/newview/llfloaterchangeitemthumbnail.cpp | 201 +++++++++++++++++++++++++ 1 file changed, 201 insertions(+) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index bd528f43dc..b267c7e0a3 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -38,10 +38,204 @@ #include "lltextbox.h" #include "lltexturectrl.h" #include "llthumbnailctrl.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(); + void notify(const std::vector& filenames) override; + +private: + LLHandle *mHandle; + LLUUID mInventoryId; + LLUUID mTaskId; +}; + +LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, LLHandle *handle) + : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE) + , mHandle(handle) + , mInventoryId(item_id) +{ +} + +LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id, LLHandle *handle) + : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE) + , mHandle(handle) + , mInventoryId(item_id) + , mTaskId(task_id) +{ +} + +LLThumbnailImagePicker::~LLThumbnailImagePicker() +{ + delete mHandle; +} + +void LLThumbnailImagePicker::notify(const std::vector& filenames) +{ + if (mHandle->isDead()) + { + return; + } + if (filenames.empty()) + { + return; + } + std::string file_path = filenames[0]; + if (file_path.empty()) + { + 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)); +} + LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key) : LLFloater(key) , mObserverInitialized(false) @@ -236,7 +430,14 @@ 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(); + LLFloater* floaterp = self->mPickerHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } } void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata) -- cgit v1.2.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 +++++++------------------ 1 file changed, 67 insertions(+), 186 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.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()); } } -- cgit v1.2.3 From d6f1ba31da4a40d62fe781419cdd7db9843f6a30 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 21 Feb 2023 14:44:45 +0200 Subject: SL-19105 Updated icons, menus and Received items panel visibility in single-folder mode --- indra/newview/llfloaterchangeitemthumbnail.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 4d76194b48..2187fda7c7 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -55,7 +55,6 @@ public: void notify(const std::vector& filenames) override; private: - LLHandle *mHandle; LLUUID mInventoryId; LLUUID mTaskId; }; -- cgit v1.2.3 From d6c0e40559fa090495b237bbbacf30578ac10aac Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 21 Feb 2023 17:53:47 +0200 Subject: SL-19108 Enabled Image changing floater for folders --- indra/newview/llfloaterchangeitemthumbnail.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 2187fda7c7..378f5bc132 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -37,6 +37,7 @@ #include "llfloaterreg.h" #include "llfloatersimplesnapshot.h" #include "lllineeditor.h" +#include "llnotificationsutil.h" #include "lltextbox.h" #include "lltexturectrl.h" #include "llthumbnailctrl.h" @@ -364,10 +365,26 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) void LLFloaterChangeItemThumbnail::onRemove(void *userdata) { LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; - LLInventoryObject* item = self->getInventoryObject(); - if (item) + + LLSD payload; + payload["item_id"] = self->mItemId; + payload["object_id"] = self->mTaskId; + LLNotificationsUtil::add("DeleteThumbnail", LLSD(), payload, boost::bind(&LLFloaterChangeItemThumbnail::onRemovalConfirmation, _1, _2, self->getHandle())); +} + +// static +void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle handle) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0 && !handle.isDead() && !handle.get()->isDead()) { - item->setThumbnailUUID(LLUUID::null); + LLFloaterChangeItemThumbnail* self = (LLFloaterChangeItemThumbnail*)handle.get(); + + LLInventoryObject* obj = self->getInventoryObject(); + if (obj) + { + obj->setThumbnailUUID(LLUUID::null); + } } } -- cgit v1.2.3 From 2d68a7c33622aa28c49989e959c2a9be1f053d03 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 21 Feb 2023 23:03:00 +0200 Subject: SL-19108 Update Simple snapshot floater --- indra/newview/llfloaterchangeitemthumbnail.cpp | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'indra/newview/llfloaterchangeitemthumbnail.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 } } -- cgit v1.2.3 From 682c9aa3c20db25c4fbaa8f5811ea0e44fa115a0 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 21 Feb 2023 23:56:47 +0200 Subject: SL-19108 Cleanup Outfit Galery Is supposed to use thumbnails now --- indra/newview/llfloaterchangeitemthumbnail.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 5b47c483fb..a78100374d 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -321,6 +321,7 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) } if (item) { + LL_INFOS() << "Setting image from outfit as a thumbnail" << LL_ENDL; thumbnail_id = item->getAssetUUID(); // per SL-19188, set this image as a thumbnail -- cgit v1.2.3 From 4886682d0458f901fc5b24ed8b58300b93489ac9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 22 Feb 2023 21:28:04 +0200 Subject: SL-19108 Multi instance snapshot floater --- indra/newview/llfloaterchangeitemthumbnail.cpp | 40 ++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index a78100374d..ab9d6135f8 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -356,18 +356,41 @@ void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata) { floaterp->closeFloater(); } + floaterp = self->mSnapshotHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } } void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata) { LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; - LLFloaterReg::toggleInstanceOrBringToFront("simple_snapshot"); - LLFloaterSimpleSnapshot* snapshot_floater = LLFloaterSimpleSnapshot::getInstance(); - if (snapshot_floater) + LLFloater* floaterp = self->mSnapshotHandle.get(); + // Show the dialog + if (floaterp) + { + floaterp->openFloater(); + } + else + { + LLSD key; + key["item_id"] = self->mItemId; + key["task_id"] = self->mTaskId; + LLFloaterSimpleSnapshot* snapshot_floater = (LLFloaterSimpleSnapshot*)LLFloaterReg::showInstance("simple_snapshot", key, true); + if (snapshot_floater) + { + self->addDependentFloater(snapshot_floater); + self->mSnapshotHandle = snapshot_floater->getHandle(); + snapshot_floater->setOwner(self); + } + } + + floaterp = self->mPickerHandle.get(); + if (floaterp) { - snapshot_floater->setInventoryId(self->mItemId); - snapshot_floater->setTaskId(self->mTaskId); + floaterp->closeFloater(); } } @@ -380,6 +403,11 @@ void LLFloaterChangeItemThumbnail::onUseTexture(void *userdata) self->showTexturePicker(obj->getThumbnailUUID()); } + LLFloater* floaterp = self->mSnapshotHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } } void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) @@ -482,6 +510,8 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) texture_floaterp->setBakeTextureEnabled(FALSE); texture_floaterp->setCanApplyImmediately(false); texture_floaterp->setCanApply(false, true); + + addDependentFloater(texture_floaterp); } floaterp->openFloater(); -- cgit v1.2.3 From dd656390c3b6cbdfc6e88c8ff3e6a011238b6f6e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 25 Feb 2023 23:08:38 +0200 Subject: SL-19108 Only permit 64 to 256 px images for thumbnails --- indra/newview/llfloaterchangeitemthumbnail.cpp | 60 +++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index ab9d6135f8..cdb09f4c6c 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -324,9 +324,12 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) LL_INFOS() << "Setting image from outfit as a thumbnail" << LL_ENDL; 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 + if (validateAsset(thumbnail_id)) + { + // per SL-19188, set this image as a thumbnail + cat->setThumbnailUUID(thumbnail_id); + // todo: needs to trigger send/update once server support is done + } } } } @@ -430,8 +433,16 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) LLInventoryObject* obj = self->getInventoryObject(); if (obj) { - obj->setThumbnailUUID(objects[0]); - // todo: need to trigger send/update once server support is done + LLUUID asset_id = objects[0]; + if (validateAsset(asset_id)) + { + obj->setThumbnailUUID(asset_id); + // todo: need to trigger send/update once server support is done + } + else + { + LLNotificationsUtil::add("ThumbnailDimantionsLimit"); + } } } } @@ -463,6 +474,33 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio } } +bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) +{ + LLPointer texturep = LLViewerTextureManager::getFetchedTexture(asset_id); + + if (!texturep) + { + return false; + } + + if (texturep->getFullWidth() != texturep->getFullHeight()) + { + return false; + } + + if (texturep->getFullWidth() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX + || texturep->getFullHeight() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX) + { + return false; + } + + if (texturep->getFullWidth() < LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN + || texturep->getFullHeight() < LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN) + { + return false; + } +} + void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) { // show hourglass cursor when loading inventory window @@ -526,8 +564,16 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) if (obj && floaterp) { - obj->setThumbnailUUID(floaterp->getAssetID()); - // todo: need to trigger send/update once server support is done + LLUUID asset_id = floaterp->getAssetID(); + if (validateAsset(asset_id)) + { + obj->setThumbnailUUID(asset_id); + // todo: need to trigger send/update once server support is done + } + else + { + LLNotificationsUtil::add("ThumbnailDimantionsLimit"); + } } } -- cgit v1.2.3 From 8795da7c831c61cfa1cb8c14ebcea7cd6c484e23 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sun, 26 Feb 2023 13:14:06 +0200 Subject: SL-19108 Only permit 64 to 256 px images for thumbnails #2 --- indra/newview/llfloaterchangeitemthumbnail.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index cdb09f4c6c..626265fd4b 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -499,6 +499,7 @@ bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) { return false; } + return true; } void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) -- cgit v1.2.3 From 011ca928ca55b8358962353a8d5aa998212c4214 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 3 Mar 2023 21:30:34 +0200 Subject: SL-19282 Send update to server side --- indra/newview/llfloaterchangeitemthumbnail.cpp | 66 ++++++++++++++++---------- 1 file changed, 41 insertions(+), 25 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 626265fd4b..722adcc254 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -327,8 +327,7 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) if (validateAsset(thumbnail_id)) { // per SL-19188, set this image as a thumbnail - cat->setThumbnailUUID(thumbnail_id); - // todo: needs to trigger send/update once server support is done + setThumbnailId(thumbnail_id); } } } @@ -430,19 +429,14 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) LLClipboard::instance().pasteFromClipboard(objects); if (objects.size() > 0) { - LLInventoryObject* obj = self->getInventoryObject(); - if (obj) + LLUUID asset_id = objects[0]; + if (validateAsset(asset_id)) { - LLUUID asset_id = objects[0]; - if (validateAsset(asset_id)) - { - obj->setThumbnailUUID(asset_id); - // todo: need to trigger send/update once server support is done - } - else - { - LLNotificationsUtil::add("ThumbnailDimantionsLimit"); - } + self->setThumbnailId(asset_id); + } + else + { + LLNotificationsUtil::add("ThumbnailDimantionsLimit"); } } } @@ -464,13 +458,7 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio if (option == 0 && !handle.isDead() && !handle.get()->isDead()) { LLFloaterChangeItemThumbnail* self = (LLFloaterChangeItemThumbnail*)handle.get(); - - LLInventoryObject* obj = self->getInventoryObject(); - if (obj) - { - obj->setThumbnailUUID(LLUUID::null); - // todo: need to trigger send/update once server support is done - } + self->setThumbnailId(LLUUID::null); } } @@ -561,15 +549,13 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) { LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mPickerHandle.get(); - LLInventoryObject* obj = getInventoryObject(); - if (obj && floaterp) + if (floaterp) { LLUUID asset_id = floaterp->getAssetID(); if (validateAsset(asset_id)) { - obj->setThumbnailUUID(asset_id); - // todo: need to trigger send/update once server support is done + setThumbnailId(asset_id); } else { @@ -578,6 +564,36 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) } } + +void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID &new_thumbnail_id) +{ + LLInventoryObject* obj = getInventoryObject(); + if (!obj) + { + return; + } + + if (mTaskId.notNull()) + { + LL_ERRS() << "Not implemented yet" << LL_ENDL; + } + else if (obj->getThumbnailUUID() != new_thumbnail_id) + { + LLSD updates; + updates["thumbnail"] = LLSD().with("asset_id", new_thumbnail_id); + LLViewerInventoryCategory* view_folder = dynamic_cast(obj); + if (view_folder) + { + update_inventory_category(mItemId, updates, NULL); + } + LLViewerInventoryItem* view_item = dynamic_cast(obj); + if (view_item) + { + update_inventory_item(mItemId, updates, NULL); + } + } +} + void LLFloaterChangeItemThumbnail::onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state) { mTooltipState = state; -- cgit v1.2.3 From 05a4485082b07208a3b5b8d5c2070243cb237e42 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 29 Mar 2023 19:43:19 +0300 Subject: SL-19504 Allow using inventory items as thumbnails from clipboard --- indra/newview/llfloaterchangeitemthumbnail.cpp | 39 ++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 722adcc254..a10de8ba23 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -429,15 +429,42 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) LLClipboard::instance().pasteFromClipboard(objects); if (objects.size() > 0) { - LLUUID asset_id = objects[0]; - if (validateAsset(asset_id)) + LLUUID potential_uuid = objects[0]; + LLUUID asset_id; + + if (potential_uuid.notNull()) { - self->setThumbnailId(asset_id); + LLViewerInventoryItem* item = gInventory.getItem(potential_uuid); + if (item) + { + // no point checking snapshot? + if (item->getType() == LLAssetType::AT_TEXTURE) + { + asset_id = item->getAssetUUID(); + } + } + else + { + LLPointer texturep = LLViewerTextureManager::getFetchedTexture(potential_uuid); + if (texturep) + { + asset_id = potential_uuid; + } + } } - else + if (asset_id.notNull()) { - LLNotificationsUtil::add("ThumbnailDimantionsLimit"); + // 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"); + } } + // else show 'buffer has no texture' warning? } } @@ -559,7 +586,7 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) } else { - LLNotificationsUtil::add("ThumbnailDimantionsLimit"); + LLNotificationsUtil::add("ThumbnailDimentionsLimit"); } } } -- cgit v1.2.3 From 8ed39a469b1b7337855c113f785fb64e66cf3b8f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 29 Mar 2023 21:30:46 +0300 Subject: SL-19504 Allow drag and drop of textures into thumbnail floater --- indra/newview/llfloaterchangeitemthumbnail.cpp | 151 ++++++++++++++++++++++--- 1 file changed, 134 insertions(+), 17 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') 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 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 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(getHandle()), + NULL, + FALSE); + } + else + { + if (validateAsset(asset_id)) + { + setThumbnailId(asset_id); + } + else + { + LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + } + } +} +bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) +{ + LLPointer 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* handle = (LLHandle*)userdata; + + if (success && !handle->isDead()) + { + LLFloaterChangeItemThumbnail* self = static_cast(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 -- cgit v1.2.3 From 77753a31aba6123696761aeeb2c535768fd1ea12 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 4 Apr 2023 02:08:23 +0300 Subject: SL-19188 Improve legacy gallery thumbnail support --- indra/newview/llfloaterchangeitemthumbnail.cpp | 32 +++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 8f6d984aa9..099ceea821 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -335,7 +335,7 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) LLViewerInventoryItem* item = dynamic_cast(obj); if (item) { - // This floater probably shouldn't be be possible to open + // This floater probably shouldn't be possible to open // for imcomplete items llassert(item->isFinished()); @@ -369,13 +369,14 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) } if (item) { - LL_INFOS() << "Setting image from outfit as a thumbnail" << LL_ENDL; thumbnail_id = item->getAssetUUID(); - - if (validateAsset(thumbnail_id)) + if (thumbnail_id.notNull()) { // per SL-19188, set this image as a thumbnail - setThumbnailId(thumbnail_id); + LL_INFOS() << "Setting image " << thumbnail_id + << " from outfit as a thumbnail for inventory object " << obj->getUUID() + << LL_ENDL; + assignAndValidateAsset(thumbnail_id, true); } } } @@ -540,11 +541,20 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio } } -void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id) +void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id, bool silent) { LLPointer texturep = LLViewerTextureManager::getFetchedTexture(asset_id); if (texturep->getFullWidth() == 0 && !texturep->isFullyLoaded() && !texturep->isMissingAsset()) { + if (silent) + { + mExpectingAssetId = LLUUID::null; + } + else + { + // don't warn user multiple times if some textures took their time + mExpectingAssetId = asset_id; + } texturep->setLoadedCallback(onImageLoaded, MAX_DISCARD_LEVEL, // don't actually need max one, 3 or 4 should be enough FALSE, @@ -559,7 +569,7 @@ void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id { setThumbnailId(asset_id); } - else + else if (!silent) { LLNotificationsUtil::add("ThumbnailDimentionsLimit"); } @@ -567,6 +577,11 @@ void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id } bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) { + if (asset_id.isNull()) + { + return false; + } + LLPointer texturep = LLViewerTextureManager::findFetchedTexture(asset_id, TEX_LIST_STANDARD); if (!texturep) @@ -624,9 +639,10 @@ void LLFloaterChangeItemThumbnail::onImageLoaded( { self->setThumbnailId(asset_id); } - else + else if (self->mExpectingAssetId == asset_id) { LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + self->mExpectingAssetId = LLUUID::null; } } } -- cgit v1.2.3 From c6d2bf93c02c6099f4c86a3379c3e82e21f9f37e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 12 Apr 2023 20:06:23 +0300 Subject: SL-19496 Recent server change requires thumbnail ids to be passed as strings --- indra/newview/llfloaterchangeitemthumbnail.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 099ceea821..4249ae9305 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -740,7 +740,8 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID &new_thumbnail_id else if (obj->getThumbnailUUID() != new_thumbnail_id) { LLSD updates; - updates["thumbnail"] = LLSD().with("asset_id", new_thumbnail_id); + // At the moment server expects id as a string + updates["thumbnail"] = LLSD().with("asset_id", new_thumbnail_id.asString()); LLViewerInventoryCategory* view_folder = dynamic_cast(obj); if (view_folder) { -- cgit v1.2.3 From b4d0aeee37973525589223842e149caa28dea2af Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 12 May 2023 19:17:31 +0300 Subject: SL-19712 Folders and items shouldn't be both called items --- indra/newview/llfloaterchangeitemthumbnail.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 4249ae9305..3070c437bd 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -335,6 +335,7 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) LLViewerInventoryItem* item = dynamic_cast(obj); if (item) { + setTitle(getString("title_item_thumbnail")); // This floater probably shouldn't be possible to open // for imcomplete items llassert(item->isFinished()); @@ -348,6 +349,7 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) if (cat) { + setTitle(getString("title_folder_thumbnail")); icon_img = LLUI::getUIImage(LLViewerFolderType::lookupIconName(cat->getPreferredType(), true)); if (thumbnail_id.isNull() && (cat->getPreferredType() == LLFolderType::FT_OUTFIT)) -- cgit v1.2.3 From 8c0ad5425f4f7497fcb3973623d8620d7088e28a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 22 May 2023 22:14:58 +0300 Subject: SL-19748 Fix thumbnail not applying if floater was closed too fast --- indra/newview/llfloaterchangeitemthumbnail.cpp | 64 ++++++++++++++++++-------- 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 3070c437bd..1ac6ee72bf 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -336,9 +336,6 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) if (item) { setTitle(getString("title_item_thumbnail")); - // This floater probably shouldn't 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))); @@ -543,6 +540,13 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio } } +struct ImageLoadedData +{ + LLUUID mThumbnailId; + LLUUID mObjectId; + LLHandle mFloaterHandle; +}; + void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id, bool silent) { LLPointer texturep = LLViewerTextureManager::getFetchedTexture(asset_id); @@ -557,11 +561,16 @@ void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id // don't warn user multiple times if some textures took their time mExpectingAssetId = asset_id; } + ImageLoadedData *data = new ImageLoadedData(); + data->mObjectId = mItemId; + data->mThumbnailId = asset_id; + data->mFloaterHandle = getHandle(); + texturep->setLoadedCallback(onImageLoaded, MAX_DISCARD_LEVEL, // don't actually need max one, 3 or 4 should be enough FALSE, FALSE, - new LLHandle(getHandle()), + (void*)data, NULL, FALSE); } @@ -629,19 +638,21 @@ void LLFloaterChangeItemThumbnail::onImageLoaded( if (!final && success) return; //not done yet - LLHandle* handle = (LLHandle*)userdata; + ImageLoadedData* data = (ImageLoadedData*)userdata; - if (success && !handle->isDead()) + if (success) { - LLFloaterChangeItemThumbnail* self = static_cast(handle->get()); - if (self) + // Update the item, set it even if floater is dead + if (validateAsset(data->mThumbnailId)) { - LLUUID asset_id = src_vi->getID(); - if (validateAsset(asset_id)) - { - self->setThumbnailId(asset_id); - } - else if (self->mExpectingAssetId == asset_id) + setThumbnailId(data->mThumbnailId, data->mObjectId); + } + + // Update floater + if (!data->mFloaterHandle.isDead()) + { + LLFloaterChangeItemThumbnail* self = static_cast(data->mFloaterHandle.get()); + if (self && self->mExpectingAssetId == data->mThumbnailId) { LLNotificationsUtil::add("ThumbnailDimentionsLimit"); self->mExpectingAssetId = LLUUID::null; @@ -649,7 +660,7 @@ void LLFloaterChangeItemThumbnail::onImageLoaded( } } - delete handle; + delete data; } void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) @@ -738,8 +749,25 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID &new_thumbnail_id if (mTaskId.notNull()) { LL_ERRS() << "Not implemented yet" << LL_ENDL; + return; } - else if (obj->getThumbnailUUID() != new_thumbnail_id) + + setThumbnailId(new_thumbnail_id, mItemId, obj); +} + +void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id) +{ + LLInventoryObject* obj = gInventory.getObject(object_id); + if (!obj) + { + return; + } + + setThumbnailId(new_thumbnail_id, object_id, obj); +} +void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id, LLInventoryObject* obj) +{ + if (obj->getThumbnailUUID() != new_thumbnail_id) { LLSD updates; // At the moment server expects id as a string @@ -747,12 +775,12 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID &new_thumbnail_id LLViewerInventoryCategory* view_folder = dynamic_cast(obj); if (view_folder) { - update_inventory_category(mItemId, updates, NULL); + update_inventory_category(object_id, updates, NULL); } LLViewerInventoryItem* view_item = dynamic_cast(obj); if (view_item) { - update_inventory_item(mItemId, updates, NULL); + update_inventory_item(object_id, updates, NULL); } } } -- cgit v1.2.3 From caa21f9054c51eea6557c9f0d080d91e43e44018 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 30 May 2023 22:08:51 +0300 Subject: SL-19748 Thumbnail to clipboard not working --- indra/newview/llfloaterchangeitemthumbnail.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 1ac6ee72bf..c3392889fb 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -468,6 +468,7 @@ void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) LLInventoryObject* obj = self->getInventoryObject(); if (obj) { + LLClipboard::instance().reset(); LLClipboard::instance().addToClipboard(obj->getThumbnailUUID(), LLAssetType::AT_NONE); self->mPasteFromClipboardBtn->setEnabled(true); } -- cgit v1.2.3 From f608eafc3724899a16d01d4b9464a21f8fbc08d3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 16 Jun 2023 22:22:59 +0300 Subject: SL-19496 Fix attempts to open trash for thumnail assigment do not work. --- indra/newview/llfloaterchangeitemthumbnail.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index c3392889fb..48378cb724 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -295,8 +295,8 @@ void LLFloaterChangeItemThumbnail::refreshFromInventory() if (obj) { const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - bool in_trash = (obj->getUUID() == trash_id) || gInventory.isObjectDescendentOf(obj->getUUID(), trash_id); - if (in_trash) + bool in_trash = gInventory.isObjectDescendentOf(obj->getUUID(), trash_id); + if (in_trash && obj->getUUID() != trash_id) { // Close properties when moving to trash // Aren't supposed to view properties from trash -- cgit v1.2.3 From 7c100d54dda03db62a8d2c8be6a5e02ea9280f9b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 29 Jun 2023 02:33:58 +0300 Subject: SL-19928 Make thumbnail selection failures more user friendly --- indra/newview/llfloaterchangeitemthumbnail.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 48378cb724..1ad235ac0a 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -710,7 +710,9 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) texture_floaterp->setLocalTextureEnabled(FALSE); texture_floaterp->setBakeTextureEnabled(FALSE); texture_floaterp->setCanApplyImmediately(false); - texture_floaterp->setCanApply(false, true); + texture_floaterp->setCanApply(false, true, false /*Hide 'preview disabled'*/); + texture_floaterp->setDimentionsLimits(LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX, + LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN); addDependentFloater(texture_floaterp); } -- cgit v1.2.3 From 7b9206dfd15ee90fde421525254b0a29d94f1ef2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 22 Jul 2023 00:22:35 +0300 Subject: SL-20045 Texture picker should apply the exact texture inventory item --- indra/newview/llfloaterchangeitemthumbnail.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 1ad235ac0a..d7fbf1384b 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -698,11 +698,11 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) { //texture_floaterp->setTextureSelectedCallback(); //texture_floaterp->setOnUpdateImageStatsCallback(); - texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&) { if (op == LLTextureCtrl::TEXTURE_SELECT) { - onTexturePickerCommit(id); + onTexturePickerCommit(); } } ); @@ -722,7 +722,7 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) floaterp->setFocus(TRUE); } -void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) +void LLFloaterChangeItemThumbnail::onTexturePickerCommit() { LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mPickerHandle.get(); -- cgit v1.2.3 From 5048b3878c027859dcc9005dff550f0afc38f623 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Aug 2023 22:31:46 +0300 Subject: SL-20101 Fix ThumbnailDimentionsLimit poping up on success --- indra/newview/llfloaterchangeitemthumbnail.cpp | 34 ++++++++++++++++++-------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index d7fbf1384b..692ef3b163 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -546,12 +546,21 @@ struct ImageLoadedData LLUUID mThumbnailId; LLUUID mObjectId; LLHandle mFloaterHandle; + bool mSilent; }; void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id, bool silent) { LLPointer texturep = LLViewerTextureManager::getFetchedTexture(asset_id); - if (texturep->getFullWidth() == 0 && !texturep->isFullyLoaded() && !texturep->isMissingAsset()) + if (texturep->isMissingAsset()) + { + LL_WARNS() << "Attempted to assign missing asset " << asset_id << LL_ENDL; + if (!silent) + { + LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + } + } + else if (texturep->getFullWidth() == 0) { if (silent) { @@ -566,9 +575,10 @@ void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id data->mObjectId = mItemId; data->mThumbnailId = asset_id; data->mFloaterHandle = getHandle(); + data->mSilent = silent; texturep->setLoadedCallback(onImageLoaded, - MAX_DISCARD_LEVEL, // don't actually need max one, 3 or 4 should be enough + MAX_DISCARD_LEVEL, // Don't need full image, just size data FALSE, FALSE, (void*)data, @@ -648,16 +658,20 @@ void LLFloaterChangeItemThumbnail::onImageLoaded( { setThumbnailId(data->mThumbnailId, data->mObjectId); } + else if (!data->mSilent) + { + // Should this only appear if floater is alive? + LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + } + } - // Update floater - if (!data->mFloaterHandle.isDead()) + // Update floater + if (!data->mSilent && !data->mFloaterHandle.isDead()) + { + LLFloaterChangeItemThumbnail* self = static_cast(data->mFloaterHandle.get()); + if (self && self->mExpectingAssetId == data->mThumbnailId) { - LLFloaterChangeItemThumbnail* self = static_cast(data->mFloaterHandle.get()); - if (self && self->mExpectingAssetId == data->mThumbnailId) - { - LLNotificationsUtil::add("ThumbnailDimentionsLimit"); - self->mExpectingAssetId = LLUUID::null; - } + self->mExpectingAssetId = LLUUID::null; } } -- cgit v1.2.3 From 4b5b048cb6280cbd9fd303acd96fce73461d1fb4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 22 Aug 2023 21:14:06 +0300 Subject: SL-20187 [AIS3] Don't fill thumbnail field if null thumbnail is set --- indra/newview/llfloaterchangeitemthumbnail.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 692ef3b163..77212507ab 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -787,8 +787,16 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id if (obj->getThumbnailUUID() != new_thumbnail_id) { LLSD updates; - // At the moment server expects id as a string - updates["thumbnail"] = LLSD().with("asset_id", new_thumbnail_id.asString()); + if (new_thumbnail_id.notNull()) + { + // At the moment server expects id as a string + updates["thumbnail"] = LLSD().with("asset_id", new_thumbnail_id.asString()); + } + else + { + // No thumbnail isntead of 'null id thumbnail' + updates["thumbnail"] = LLSD(); + } LLViewerInventoryCategory* view_folder = dynamic_cast(obj); if (view_folder) { -- cgit v1.2.3 From cfb69846f1e8309ed86d4a18eb26a889f6dbaccc Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 9 Sep 2023 00:00:22 +0300 Subject: SL-20261 Allow and resize existing textures as necessary for thumbnails --- indra/newview/llfloaterchangeitemthumbnail.cpp | 132 +++++++++++++++++++++++-- 1 file changed, 126 insertions(+), 6 deletions(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 77212507ab..780130039b 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -512,6 +512,13 @@ void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) asset_id = potential_uuid; } } + + LLInventoryObject* obj = self->getInventoryObject(); + if (obj && obj->getThumbnailUUID() == asset_id) + { + // nothing to do + return; + } if (asset_id.notNull()) { self->assignAndValidateAsset(asset_id); @@ -547,6 +554,8 @@ struct ImageLoadedData LLUUID mObjectId; LLHandle mFloaterHandle; bool mSilent; + // Keep image reference to prevent deletion on timeout + LLPointer mTexturep; }; void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id, bool silent) @@ -576,8 +585,9 @@ void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id data->mThumbnailId = asset_id; data->mFloaterHandle = getHandle(); data->mSilent = silent; + data->mTexturep = texturep; - texturep->setLoadedCallback(onImageLoaded, + texturep->setLoadedCallback(onImageDataLoaded, MAX_DISCARD_LEVEL, // Don't need full image, just size data FALSE, FALSE, @@ -636,7 +646,7 @@ bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) } //static -void LLFloaterChangeItemThumbnail::onImageLoaded( +void LLFloaterChangeItemThumbnail::onImageDataLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, @@ -678,6 +688,45 @@ void LLFloaterChangeItemThumbnail::onImageLoaded( delete data; } +//static +void LLFloaterChangeItemThumbnail::onFullImageLoaded( + 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 + + ImageLoadedData* data = (ImageLoadedData*)userdata; + + if (success) + { + if (src_vi->getFullWidth() != src_vi->getFullHeight() + || src_vi->getFullWidth() < LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN) + { + if (!data->mSilent) + { + LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + } + } + else if (src_vi->getFullWidth() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX) + { + LLFloaterSimpleSnapshot::uploadThumbnail(src, data->mObjectId, LLUUID::null); + } + else + { + setThumbnailId(data->mThumbnailId, data->mObjectId); + } + } + + delete data; +} + void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) { // show hourglass cursor when loading inventory window @@ -725,8 +774,7 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) texture_floaterp->setBakeTextureEnabled(FALSE); texture_floaterp->setCanApplyImmediately(false); texture_floaterp->setCanApply(false, true, false /*Hide 'preview disabled'*/); - texture_floaterp->setDimentionsLimits(LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX, - LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN); + texture_floaterp->setMinDimentionsLimits(LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN); addDependentFloater(texture_floaterp); } @@ -743,14 +791,86 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit() if (floaterp) { LLUUID asset_id = floaterp->getAssetID(); - if (validateAsset(asset_id)) + + if (asset_id.isNull()) { setThumbnailId(asset_id); + return; } - else + + LLInventoryObject* obj = getInventoryObject(); + if (obj && obj->getThumbnailUUID() == asset_id) + { + // nothing to do + return; + } + + LLPointer texturep = LLViewerTextureManager::findFetchedTexture(asset_id, TEX_LIST_STANDARD); + if (!texturep) + { + LL_WARNS() << "Image " << asset_id << " doesn't exist" << LL_ENDL; + return; + } + + if (texturep->isMissingAsset()) + { + LL_WARNS() << "Image " << asset_id << " is missing" << LL_ENDL; + return; + } + + if (texturep->getFullWidth() != texturep->getFullHeight()) + { + LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + return; + } + + if (texturep->getFullWidth() < LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN + && texturep->getFullWidth() > 0) { LLNotificationsUtil::add("ThumbnailDimentionsLimit"); + return; + } + + if (texturep->getFullWidth() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX + || texturep->getFullWidth() == 0) + { + if (texturep->isFullyLoaded() + && (texturep->getCachedRawImageLevel() == 0 || texturep->getRawImageLevel() == 0) + && (texturep->isCachedRawImageReady() || texturep->isRawImageValid())) + { + if (texturep->isRawImageValid()) + { + LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getRawImage(), mItemId, mTaskId); + } + else + { + LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getCachedRawImage(), mItemId, mTaskId); + } + } + else + { + ImageLoadedData* data = new ImageLoadedData(); + data->mObjectId = mItemId; + data->mThumbnailId = asset_id; + data->mFloaterHandle = getHandle(); + data->mSilent = false; + data->mTexturep = texturep; + + texturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + texturep->setMinDiscardLevel(0); + texturep->setLoadedCallback(onFullImageLoaded, + 0, // Need best quality + TRUE, + FALSE, + (void*)data, + NULL, + FALSE); + texturep->forceToSaveRawImage(0); + } + return; } + + setThumbnailId(asset_id); } } -- cgit v1.2.3 From 5566f28b039e2f3999e397a26243707affc80991 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 3 Oct 2023 19:27:26 +0300 Subject: D559 Post merge fixes --- indra/newview/llfloaterchangeitemthumbnail.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview/llfloaterchangeitemthumbnail.cpp') diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 780130039b..f54240f6f4 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -750,7 +750,6 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) "SELECT PHOTO", PERM_NONE, PERM_NONE, - PERM_NONE, FALSE, NULL); -- cgit v1.2.3