diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-03-30 18:32:42 +0300 |
---|---|---|
committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-03-30 18:35:47 +0300 |
commit | 8f6d149fadf635f6698e2e68aa4f48db13eff648 (patch) | |
tree | a86adf0a7c38c4d0ced579ed364187a26af7f9d9 /indra/newview | |
parent | cd61dbe6eea8d9a7e4bdb594179bafc24a504146 (diff) |
SL-16937 New Profile capability, image uploader for testing
This commit is mostly to simplify cap testing for server side. Plan is to remove LLLocalBitmap and draw texture more directly instead
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/lllocalbitmaps.cpp | 60 | ||||
-rw-r--r-- | indra/newview/lllocalbitmaps.h | 1 | ||||
-rw-r--r-- | indra/newview/llpanelprofile.cpp | 141 | ||||
-rw-r--r-- | indra/newview/llpanelprofile.h | 10 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_profile_secondlife.xml | 17 |
5 files changed, 165 insertions, 64 deletions
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 5a17332fde..de8db69e19 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -919,6 +919,36 @@ LLLocalBitmapMgr::~LLLocalBitmapMgr() mBitmapList.clear(); } +LLUUID LLLocalBitmapMgr::addUnit(const std::string &filename) +{ + if (!checkTextureDimensions(filename)) + { + return LLUUID::null; + } + + LLLocalBitmap* unit = new LLLocalBitmap(filename); + + if (unit->getValid()) + { + mBitmapList.push_back(unit); + return unit->getTrackingID(); + } + else + { + LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n" + << "Filename: " << filename << LL_ENDL; + + LLSD notif_args; + notif_args["FNAME"] = filename; + LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args); + + delete unit; + unit = NULL; + } + + return LLUUID::null; +} + bool LLLocalBitmapMgr::addUnit() { bool add_successful = false; @@ -931,32 +961,10 @@ bool LLLocalBitmapMgr::addUnit() std::string filename = picker.getFirstFile(); while(!filename.empty()) { - if(!checkTextureDimensions(filename)) - { - filename = picker.getNextFile(); - continue; - } - - LLLocalBitmap* unit = new LLLocalBitmap(filename); - - if (unit->getValid()) - { - mBitmapList.push_back(unit); - add_successful = true; - } - else - { - LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n" - << "Filename: " << filename << LL_ENDL; - - LLSD notif_args; - notif_args["FNAME"] = filename; - LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args); - - delete unit; - unit = NULL; - } - + if (addUnit(filename).notNull()) + { + add_successful = true; + } filename = picker.getNextFile(); } diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index d5ee7efdc6..c29f3f62f6 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -116,6 +116,7 @@ class LLLocalBitmapMgr : public LLSingleton<LLLocalBitmapMgr> ~LLLocalBitmapMgr(); public: bool addUnit(); + LLUUID addUnit(const std::string &filename); void delUnit(LLUUID tracking_id); bool checkTextureDimensions(std::string filename); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 156d2671f4..c19688191b 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -58,6 +58,7 @@ #include "llcallingcard.h" #include "llcommandhandler.h" #include "llfloaterreg.h" +#include "llfilepicker.h" #include "llfirstuse.h" #include "llgroupactions.h" #include "llmutelist.h" @@ -68,6 +69,7 @@ #include "lltrans.h" #include "llviewercontrol.h" #include "llviewermenu.h" //is_agent_mappable +#include "llviewermenufile.h" #include "llviewertexturelist.h" #include "llvoiceclient.h" #include "llweb.h" @@ -324,17 +326,20 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s if (!status) { LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; + LLFile::remove(path_to_image); return; } if (!result.has("uploader")) { LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; + LLFile::remove(path_to_image); return; } std::string uploader_cap = result["uploader"].asString(); if (uploader_cap.empty()) { LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; + LLFile::remove(path_to_image); return; } @@ -350,6 +355,7 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s if (!instream.is_open()) { LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; + LLFile::remove(path_to_image); return; } length = instream.tellg(); @@ -367,6 +373,7 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s if (!status) { LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; + LLFile::remove(path_to_image); return; } @@ -380,6 +387,7 @@ void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::s { LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL; } + LLFile::remove(path_to_image); return; } @@ -575,6 +583,8 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife() { mAvatarNameCacheConnection.disconnect(); } + + clearUploadProfileImagePath(); } BOOL LLPanelProfileSecondLife::postBuild() @@ -582,7 +592,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mStatusText = getChild<LLTextBox>("status"); mGroupList = getChild<LLGroupList>("group_list"); mShowInSearchCheckbox = getChild<LLCheckBoxCtrl>("show_in_search_checkbox"); - mSecondLifePic = getChild<LLTextureCtrl>("2nd_life_pic"); + mSecondLifePic = getChild<LLIconCtrl>("2nd_life_pic"); mSecondLifePicLayout = getChild<LLPanel>("image_stack"); mDescriptionEdit = getChild<LLTextBase>("sl_description_edit"); mTeleportButton = getChild<LLButton>("teleport"); @@ -610,7 +620,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mUnblockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); mGroupInviteButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onGroupInvite,this)); mDisplayNameButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickSetName, this)); - mSecondLifePic->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onCommitTexture, this)); + mSecondLifePic->setMouseUpCallback(boost::bind(&LLPanelProfileSecondLife::onPickTexture, this)); LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit; commit.add("Profile.CopyName", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); }); @@ -650,8 +660,6 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mGroupList->setShowNone(!own_profile); mGiveInvPanel->setVisible(!own_profile); - mSecondLifePic->setOpenTexPreview(!own_profile); - if (own_profile && !getEmbedded()) { // Group list control cannot toggle ForAgent loading @@ -693,10 +701,11 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) LLSD params = LLSDMap(); // we have an image, check if it is local. Server won't recognize local ids. - if (data->image_id != mSecondLifePic->getImageAssetID() - && !LLLocalBitmapMgr::getInstance()->isLocal(mSecondLifePic->getImageAssetID())) + if (data->image_id != mImageAssetId + && mImageFile.empty() + && !LLLocalBitmapMgr::getInstance()->isLocal(mImageAssetId)) { - params["sl_image_id"] = mSecondLifePic->getImageAssetID(); + params["sl_image_id"] = mImageAssetId; } if (data->about_text != mDescriptionEdit->getValue().asString()) { @@ -721,12 +730,19 @@ void LLPanelProfileSecondLife::apply(LLAvatarData* data) } // Only if image is local - if (data->image_id != mSecondLifePic->getImageAssetID() - && LLLocalBitmapMgr::getInstance()->isLocal(mSecondLifePic->getImageAssetID())) + if (!mImageFile.empty()) { - // todo: temporary file, connect to UI - std::string file_path = gDirUtilp->findSkinnedFilename("textures", "icons/Default_Outfit_Photo.png"); - launch_profile_image_coro(PROFILE_IMAGE_SL, file_path); + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("postAgentUserImageCoro", + boost::bind(post_profile_image_coro, cap_url, PROFILE_IMAGE_SL, mImageFile)); + mImageFile.clear(); // coro should do the deleting + } + else + { + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; + } } } } @@ -773,7 +789,7 @@ void LLPanelProfileSecondLife::resetData() getChild<LLUICtrl>("partner_text")->setValue(LLStringUtil::null); // Set default image and 1:1 dimensions for it - mSecondLifePic->setValue(mSecondLifePic->getDefaultImageAssetID()); + mSecondLifePic->setValue("Generic_Person_Large"); LLRect imageRect = mSecondLifePicLayout->getRect(); mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); @@ -782,6 +798,7 @@ void LLPanelProfileSecondLife::resetData() mCopyMenuButton->setVisible(FALSE); mGroups.clear(); mGroupList->setGroups(mGroups); + clearUploadProfileImagePath(); } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) @@ -845,6 +862,37 @@ void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const L mCopyMenuButton->setVisible(TRUE); } +void LLPanelProfileSecondLife::setUploadProfileImagePath(const std::string &path, const std::string &orig_path) +{ + clearUploadProfileImagePath(); + // todo: display this in floater, + // LLIconCtrl can't show a path, only by id or name, so may be draw directly or add as a local bitmap? + // LLLocalBitmap* unit = new LLLocalBitmap(path); + + // assign a local texture to view in viewer + // Todo: remove LLLocalBitmap and just draw texture instead + // orig_path was used instead of path, since LLLocalBitmapMgr does not support j2c + LLUUID tracking_id = LLLocalBitmapMgr::getInstance()->addUnit(orig_path); + if (tracking_id.isNull()) + { + // todo: error handling + return; + } + + mImageFile = path; + mImageAssetId = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); + mSecondLifePic->setValue(mImageAssetId); +} + +void LLPanelProfileSecondLife::clearUploadProfileImagePath() +{ + if (!mImageFile.empty()) + { + LLFile::remove(mImageFile); //todo: supress errors, may be not need to remove if it becomes a LLLocalBitmap + } + mImageFile.clear(); +} + void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) { // Refresh avatar id in cache with new info to prevent re-requests @@ -862,7 +910,8 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) std::string register_date = getString("RegisterDateFormat", args); getChild<LLUICtrl>("register_date")->setValue(register_date ); mDescriptionEdit->setValue(avatar_data->about_text); - mSecondLifePic->setValue(avatar_data->image_id); + mImageAssetId = avatar_data->image_id; + mSecondLifePic->setValue(mImageAssetId); //Don't bother about boost level, picker will set it LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); @@ -1119,23 +1168,63 @@ void LLPanelProfileSecondLife::onClickSetName() LLFirstUse::setDisplayName(false); } -void LLPanelProfileSecondLife::onCommitTexture() + + +class LLProfileImagePicker : public LLFilePickerThread { - LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(mSecondLifePic->getImageAssetID()); - if (imagep->getFullHeight()) +public: + LLProfileImagePicker(LLHandle<LLPanel> *handle); + ~LLProfileImagePicker(); + virtual void notify(const std::vector<std::string>& filenames); + +private: + LLHandle<LLPanel> *mHandle; +}; + +LLProfileImagePicker::LLProfileImagePicker(LLHandle<LLPanel> *handle) + : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE), + mHandle(handle) +{ +} + +LLProfileImagePicker::~LLProfileImagePicker() +{ + delete mHandle; +} + +void LLProfileImagePicker::notify(const std::vector<std::string>& filenames) +{ + /*if (LLAppViewer::instance()->quitRequested()) { - onImageLoaded(true, imagep); + return; + }*/ + if (mHandle->isDead()) + { + return; } - else + std::string file_path = filenames[0]; + if (file_path.empty()) { - imagep->setLoadedCallback(onImageLoaded, - MAX_DISCARD_LEVEL, - FALSE, - FALSE, - new LLHandle<LLPanel>(getHandle()), - NULL, - FALSE); + 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)) + { + // todo: error handling + return; } + + LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get()); + panel->setUploadProfileImagePath(temp_file, file_path); +} + +void LLPanelProfileSecondLife::onPickTexture() +{ + (new LLProfileImagePicker(new LLHandle<LLPanel>(getHandle())))->getFile(); } void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index e87de9f96f..9aab8a087c 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -46,6 +46,7 @@ class LLAvatarName; class LLCheckBoxCtrl; +class LLIconCtrl; class LLTabContainer; class LLTextBox; class LLTextureCtrl; @@ -102,6 +103,9 @@ public: void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + void setUploadProfileImagePath(const std::string &path, const std::string &orig_path); + void clearUploadProfileImagePath(); + friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); protected: @@ -178,7 +182,7 @@ protected: private: /*virtual*/ void updateButtons(); void onClickSetName(); - void onCommitTexture(); + void onPickTexture(); void onCommitMenu(const LLSD& userdata); void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name); @@ -190,7 +194,7 @@ private: LLTextBox* mStatusText; LLGroupList* mGroupList; LLCheckBoxCtrl* mShowInSearchCheckbox; - LLTextureCtrl* mSecondLifePic; + LLIconCtrl* mSecondLifePic; LLPanel* mSecondLifePicLayout; LLTextBase* mDescriptionEdit; LLButton* mTeleportButton; @@ -207,6 +211,8 @@ private: LLPanel* mGiveInvPanel; bool mVoiceStatus; + std::string mImageFile; + LLUUID mImageAssetId; boost::signals2::connection mAvatarNameCacheConnection; }; diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml index 816b0b8f5c..d8d2749a2b 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -177,19 +177,16 @@ auto_resize="false" user_resize="false" > - <!-- 23 pixels (BTN_HEIGHT_SMALL) are reserved by label field of texture and shouldn't be visible--> - <texture_picker + + <icon name="2nd_life_pic" + image_name="Generic_Person_Large" + layout="topleft" + follows="all" top="0" left="0" - right="-1" - height="180" - follows="all" - layout="topleft" - allow_no_texture="true" - default_image_name="None" - fallback_image="Generic_Person_Large" - /> + width="157" + height="157"/> </layout_panel> <layout_panel name="label_stack" |