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 insteadmaster
parent
cd61dbe6ee
commit
8f6d149fad
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}*/
|
||||
if (mHandle->isDead())
|
||||
{
|
||||
imagep->setLoadedCallback(onImageLoaded,
|
||||
MAX_DISCARD_LEVEL,
|
||||
FALSE,
|
||||
FALSE,
|
||||
new LLHandle<LLPanel>(getHandle()),
|
||||
NULL,
|
||||
FALSE);
|
||||
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))
|
||||
{
|
||||
// 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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue