FIRE-9608: Add object export success notification and progress floater

meow-7.2.2
Cinders 2013-08-07 11:39:36 -06:00
parent bc33015c0b
commit 31514e64c1
6 changed files with 207 additions and 4 deletions

View File

@ -44,6 +44,7 @@
#include "llmeshrepository.h"
#include "llmultigesture.h"
#include "llnotecard.h"
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "llsdutil_math.h"
#include "llsdutil.h"
@ -58,12 +59,15 @@
#include "llviewerpartsource.h"
#include "llworld.h"
#include "fscommon.h"
#include "llfloaterreg.h"
#include <boost/algorithm/string_regex.hpp>
const F32 MAX_TEXTURE_WAIT_TIME = 30.0f;
const F32 MAX_INVENTORY_WAIT_TIME = 30.0f;
const F32 MAX_ASSET_WAIT_TIME = 60.0f;
static void updateProgress(const std::string message);
// static
void FSExport::onIdle(void* user_data)
{
@ -102,6 +106,10 @@ void FSExport::onIdle()
LLViewerObject* object = gObjectList.findObject((*iter));
object->dirtyInventory();
object->requestInventory();
LLStringUtil::format_map_t args;
args["ITEM"] = (*iter).asString();
updateProgress(formatString(LLTrans::getString("export_rerequesting_inventory"), args));
LL_DEBUGS("export") << "re-requested inventory of " << (*iter).asString() << LL_ENDL;
}
}
@ -154,8 +162,12 @@ void FSExport::onIdle()
std::string zip_data = zip_llsd(mFile);
file.write(zip_data.data(), zip_data.size());
file.close();
LL_DEBUGS("export") << "Export finished and written to " << mFileName << LL_ENDL;
updateProgress(LLTrans::getString("export_finished"));
LLSD args;
args["FILENAME"] = mFileName;
LLNotificationsUtil::add("ExportFinished", args);
}
else if (mLastRequest != mRequestedTexture.size())
{
@ -172,6 +184,10 @@ void FSExport::onIdle()
image->setBoostLevel(LLViewerTexture::BOOST_MAX_LEVEL);
image->forceToSaveRawImage(0);
image->setLoadedCallback(FSExport::onImageLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList);
LLStringUtil::format_map_t args;
args["ITEM"] = texture_id.asString();
updateProgress(formatString(LLTrans::getString("export_rerequesting_texture"), args));
LL_DEBUGS("export") << "re-requested texture " << texture_id.asString() << LL_ENDL;
}
}
@ -190,6 +206,7 @@ void FSExport::exportSelection()
LLFilePicker& file_picker = LLFilePicker::instance();
if(!file_picker.getSaveFile(LLFilePicker::FFSAVE_EXPORT, LLDir::getScrubbedFileName(node->mName + ".oxp")))
{
llinfos << "User closed the filepicker, aborting export!" << llendl;
return;
}
mFileName = file_picker.getFirstFile();
@ -208,6 +225,8 @@ void FSExport::exportSelection()
mFile["client"] = LLAppViewer::instance()->getSecondLifeTitle() + LLVersionInfo::getChannel();
mFile["client_version"] = LLVersionInfo::getVersion();
mFile["grid"] = LLGridManager::getInstance()->getGridLabel();
LLFloaterReg::showInstance("fs_export");
updateProgress("Beginning export...");
for ( ; iter != selection->valid_root_end(); ++iter)
{
@ -223,6 +242,7 @@ void FSExport::exportSelection()
}
else
{
updateProgress(LLTrans::getString("export_nothing_exported"));
LL_WARNS("export") << "Nothing was exported. File not created." << LL_ENDL;
}
}
@ -288,6 +308,9 @@ void FSExport::addPrim(LLViewerObject* object, bool root)
else
{
LL_WARNS("export") << "LLSelect node for " << object_id.asString() << " not found. Using default prim instead." << LL_ENDL;
LLStringUtil::format_map_t args;
args["OBJECT"] = object_id.asString();
updateProgress(formatString(LLTrans::getString("export_node_not_found"), args));
default_prim = true;
}
@ -309,6 +332,10 @@ void FSExport::addPrim(LLViewerObject* object, bool root)
if (default_prim)
{
LLStringUtil::format_map_t args;
args["OBJECT"] = object_id.asString();
updateProgress(formatString(LLTrans::getString("export_failed_export_check"), args));
LL_DEBUGS("export") << object_id.asString() << " failed export check. Using default prim" << LL_ENDL;
prim["flags"] = ll_sd_from_U32((U32)0);
prim["volume"]["path"] = LLPathParams().asLLSD();
@ -343,7 +370,7 @@ void FSExport::addPrim(LLViewerObject* object, bool root)
{
if (!mAborted)
{
reportToNearbyChat(LLTrans::getString("export_fail_no_mesh"));
updateProgress(LLTrans::getString("export_fail_no_mesh"));
mAborted = true;
}
return;
@ -489,6 +516,7 @@ bool FSExport::exportTexture(const LLUUID& texture_id)
{
if(texture_id.isNull())
{
updateProgress(LLTrans::getString("export_failed_null_texture"));
LL_WARNS("export") << "Attempted to export NULL texture." << LL_ENDL;
return false;
}
@ -536,13 +564,19 @@ bool FSExport::exportTexture(const LLUUID& texture_id)
mTextureChecked[texture_id] = texture_export;
LLStringUtil::format_map_t args;
args["ITEM"] = name;
if (!texture_export)
{
updateProgress(formatString(LLTrans::getString("export_asset_failed_export_check"), args));
LL_DEBUGS("export") << "Texture " << texture_id << " failed export check." << LL_ENDL;
return false;
}
LL_DEBUGS("export") << "Loading image texture " << texture_id << LL_ENDL;
updateProgress(formatString(LLTrans::getString("export_loading_texture"), args));
mRequestedTexture[texture_id].name = name;
mRequestedTexture[texture_id].description = description;
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_id, FTT_DEFAULT, MIPMAP_TRUE);
@ -596,6 +630,8 @@ void FSExportCacheReadResponder::setData(U8* data, S32 datasize, S32 imagesize,
void FSExportCacheReadResponder::completed(bool success)
{
LLStringUtil::format_map_t args;
args["TEXTURE"] = mID.asString();
if (success && mFormattedImage.notNull() && mImageSize > 0)
{
LL_DEBUGS("export") << "SUCCESS getting texture " << mID << LL_ENDL;
@ -636,6 +672,10 @@ void FSExport::saveFormattedImage(LLPointer<LLImageFormatted> mFormattedImage, L
mFile["asset"][id.asString()]["type"] = LLAssetType::lookup(LLAssetType::AT_TEXTURE);
mFile["asset"][id.asString()]["data"] = LLSD::Binary(str.begin(),str.end());
LLStringUtil::format_map_t args;
args["TEXTURE"] = mRequestedTexture[id].name;
updateProgress(formatString(LLTrans::getString("export_saving_texture"), args));
removeRequestedTexture(id);
}
@ -729,6 +769,9 @@ void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::objec
if (!exportable)
{
LLStringUtil::format_map_t args;
args["ITEM"] = item->getName();
updateProgress(formatString(LLTrans::getString("export_asset_failed_export_check"), args));
LL_DEBUGS("export") << "Item " << item->getName() << " failed export check." << LL_ENDL;
continue;
}
@ -736,6 +779,9 @@ void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::objec
if (item->getType() == LLAssetType::AT_NONE || item->getType() == LLAssetType::AT_OBJECT)
{
// currentelly not exportable
LLStringUtil::format_map_t args;
args["ITEM"] = item->getName();
updateProgress(formatString(LLTrans::getString("export_item_not_exportable"), args));
LL_DEBUGS("export") << "Skipping " << LLAssetType::lookup(item->getType()) << " item " << item->getName() << LL_ENDL;
continue;
}
@ -764,6 +810,9 @@ void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::objec
}
else
{
LLStringUtil::format_map_t args;
args["ITEM"] = item->getName();
updateProgress(formatString(LLTrans::getString("export_requesting_asset"), args));
LL_DEBUGS("export") << "Requesting asset " << item->getAssetUUID() << " for item " << item->getUUID() << LL_ENDL;
mAssetRequests.push_back(item->getUUID());
FSAssetResourceData* data = new FSAssetResourceData;
@ -810,11 +859,19 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
if (status != 0)
{
LLStringUtil::format_map_t args;
args["ITEM"] = asset_uuid.asString();
args["STATUS"] = llformat("%d",status);
args["EXT_STATUS"] = llformat("%d",ext_status);
updateProgress(formatString(LLTrans::getString("export_failed_fetch"), args));
LL_WARNS("export") << "Problem fetching asset: " << asset_uuid << " " << status << " " << ext_status << LL_ENDL;
delete data;
return;
}
LLStringUtil::format_map_t args;
args["ITEM"] = data->name;
updateProgress(formatString(LLTrans::getString("export_saving_asset"), args));
LL_DEBUGS("export") << "Saving asset " << asset_uuid.asString() << " of item " << item_uuid.asString() << LL_ENDL;
LLVFile file(vfs, asset_uuid, type);
S32 file_length = file.getSize();
@ -852,7 +909,7 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
}
else
{
LL_DEBUGS("export") << "Invalied uuid: " << m1->str() << LL_ENDL;
LL_DEBUGS("export") << "Invalid uuid: " << m1->str() << LL_ENDL;
}
}
}
@ -864,6 +921,9 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
LLDataPackerAsciiBuffer dp((char*)&buffer[0], file_length+1);
if (!gesture->deserialize(dp))
{
LLStringUtil::format_map_t args;
args["ITEM"] = asset_uuid.asString();
updateProgress(formatString(LLTrans::getString("export_failed_to_load"), args));
LL_WARNS("export") << "Unable to load gesture " << asset_uuid << LL_ENDL;
break;
}
@ -882,6 +942,9 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
if (!self->assetCheck(anim_step->mAnimAssetID, name, description))
{
LLStringUtil::format_map_t args;
args["ITEM"] = data->name;
updateProgress(formatString(LLTrans::getString("export_asset_failed_export_check"), args));
LL_DEBUGS("export") << "Asset in gesture " << data->name << " failed export check." << LL_ENDL;
break;
}
@ -890,6 +953,10 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
anim_data->name = anim_step->mAnimName;
anim_data->user_data = self;
anim_data->uuid = anim_step->mAnimAssetID;
LLStringUtil::format_map_t args;
args["ITEM"] = anim_step->mAnimAssetID.asString();
updateProgress(formatString(LLTrans::getString("export_requesting_asset"), args));
LL_DEBUGS("export") << "Requesting animation asset " << anim_step->mAnimAssetID.asString() << LL_ENDL;
self->mAssetRequests.push_back(anim_step->mAnimAssetID);
gAssetStorage->getAssetData(anim_step->mAnimAssetID,
@ -904,6 +971,9 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
if (!self->assetCheck(sound_step->mSoundAssetID, name, description))
{
LLStringUtil::format_map_t args;
args["ITEM"] = data->name;
updateProgress(formatString(LLTrans::getString("export_asset_failed_export_check"), args));
LL_DEBUGS("export") << "Asset in gesture " << data->name << " failed export check." << LL_ENDL;
break;
}
@ -912,6 +982,10 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
sound_data->name = sound_step->mSoundName;
sound_data->user_data = self;
sound_data->uuid = sound_step->mSoundAssetID;
LLStringUtil::format_map_t args;
args["ITEM"] = sound_step->mSoundAssetID.asString();
updateProgress(formatString(LLTrans::getString("export_requesting_asset"), args));
LL_DEBUGS("export") << "Requesting sound asset " << sound_step->mSoundAssetID.asString() << LL_ENDL;
self->mAssetRequests.push_back(sound_step->mSoundAssetID);
gAssetStorage->getAssetData(sound_step->mSoundAssetID,
@ -944,3 +1018,53 @@ void FSExport::removeRequestedAsset(LLUUID asset_uuid)
mAssetRequests.erase(iter);
}
}
// static
void updateProgress(const std::string message)
{
FSFloaterObjectExport* export_floater = LLFloaterReg::findTypedInstance<FSFloaterObjectExport>("fs_export");
if (export_floater)
export_floater->updateProgress(message);
}
//-----------------------------------------------------
// FSFloaterObjectExport
//-----------------------------------------------------
FSFloaterObjectExport::FSFloaterObjectExport(const LLSD& key)
: LLFloater(key),
mOutputList(NULL)
{
}
// virtual
FSFloaterObjectExport::~FSFloaterObjectExport()
{
}
// virtual
BOOL FSFloaterObjectExport::postBuild()
{
mOutputList = getChild<LLScrollListCtrl>("export_output");
if (mOutputList)
mOutputList->deleteAllItems();
childSetAction("close_btn", boost::bind(&FSFloaterObjectExport::onCloseBtn, this));
return TRUE;
}
void FSFloaterObjectExport::onCloseBtn()
{
closeFloater();
}
void FSFloaterObjectExport::updateProgress(const std::string message)
{
if (mOutputList)
{
LLSD row;
row["columns"][0]["value"] = message;
mOutputList->addElement(row);
mOutputList->selectItemByLabel(message);
mOutputList->scrollToShowSelected();
}
}

View File

@ -33,6 +33,10 @@
#include "lltexturecache.h"
#include "llviewertexture.h"
// Floater includes
#include "llfloater.h"
#include "llscrolllistctrl.h"
struct FSAssetResourceData
{
std::string name;
@ -93,6 +97,7 @@ private:
std::map<LLUUID, bool> mTextureChecked;
bool mExported;
bool mAborted;
bool mExportError;
uuid_vec_t mInventoryRequests;
uuid_vec_t mAssetRequests;
@ -113,4 +118,18 @@ private:
LLUUID mID;
};
class FSFloaterObjectExport : public LLFloater
{
public:
FSFloaterObjectExport(const LLSD& key);
virtual ~FSFloaterObjectExport();
virtual BOOL postBuild();
void onCloseBtn();
void updateProgress(const std::string message);
private:
LLScrollListCtrl* mOutputList;
};
#endif // FS_FSEXPORT_H

View File

@ -150,6 +150,7 @@
#include "floatermedialists.h"
#include "fsareasearch.h"
#include "fscontactsfloater.h"
#include "fsexport.h"
#include "fsfloaterblocklist.h"
#include "fsfloatergroup.h"
#include "fsfloatergrouptitles.h"
@ -390,6 +391,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterBlocklist>);
LLFloaterReg::add("fs_group", "floater_fs_group.xml",&LLFloaterReg::build<FSFloaterGroup>);
LLFloaterReg::add("fs_group_titles", "floater_fs_group_titles.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterGroupTitles>);
LLFloaterReg::add("fs_export", "floater_fs_export.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterObjectExport>);
LLFloaterReg::add("fs_import", "floater_fs_import.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterImport>);
LLFloaterReg::add("fs_posestand", "floater_fs_posestand.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPoseStand>);
LLFloaterReg::add("fs_placedetails", "floater_fs_placedetails.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPlaceDetails>);

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater
name="export_log"
title="Export Object"
width="250"
height="300"
min_width="104"
min_height="100"
save_rect="true"
can_resize="true"
can_minimize="true"
can_close="true"
can_drag_on_left="false">
<scroll_list
enabled="true"
follows="all"
height="270"
layout="topleft"
left="4"
name="export_output"
top="4"
width="242" />
<button
layout="topleft"
follows="right|bottom"
height="23"
label="OK"
name="close_btn"
top_pad="1"
left="153"
width="90" />
</floater>

View File

@ -11403,5 +11403,13 @@ You are about to eject [COUNT] members from the group.
notext="Cancel"
yestext="Eject"/>
</notification>
<notification
icon="alertmodal.tga"
name="ExportFinished"
type="notify">
<tag>Export</tag>
Export finished and saved to [FILENAME].
</notification>
</notifications>

View File

@ -2573,8 +2573,26 @@ Try enclosing path to the editor with double quotes.
<string name="entering_region_distance">entered the region ([DISTANCE] m).</string>
<string name="leaving_region">left the region.</string>
<string name="export_fail_no_mesh">Exporting mesh is not currently supported. Export aborted.</string>
<string name="TotalScriptCountChangeIncrease">Total scripts in region jumped from [OLD_VALUE] to [NEW_VALUE] ([DIFFERENCE]).</string>
<string name="TotalScriptCountChangeDecrease">Total scripts in region dropped from [OLD_VALUE] to [NEW_VALUE] ([DIFFERENCE]).</string>
<string name="preproc_toggle_warning">Toggling the preprocessor will not take full effect until you close and reopen this editor.</string>
<!-- <FS:CR> Exporter messages -->
<string name="export_finished">Export finished.</string>
<string name="export_fail_no_mesh">Exporting mesh is not currently supported. Export aborted.</string>
<string name="export_nothing_exported">Nothing was exported. Backup not created.</string>
<string name="export_node_not_found">LLSelect node for [OBJECT] not found. Using default prim instead.</string>
<string name="export_failed_export_check">[OBJECT] failed permissions check. Using default prim.</string>
<string name="export_asset_failed_export_check">[ITEM] failed permissions check. Skipping.</string>
<string name="export_failed_export_null_texture">Attempted to export null texture.</string>
<string name="export_loading_texture">Loading texture [ITEM]...</string>
<string name="export_saving_texture">Successfully saved texture [TEXTURE].</string>
<string name="export_failed_to_receive_texture">Failed to get texture [TEXTURE].</string>
<string name="export_received_null_texture">Received null texture [TEXTURE].</string>
<string name="export_item_not_exportable">[ITEM] is not an currently supported by the exporter. Skipping.</string>
<string name="export_failed_fetch">Could not retrieve [ITEM]. (Status [STATUS] [EXT_STATUS])</string>
<string name="export_requesting_asset">Requesting asset [ITEM]...</string>
<string name="export_rerequesting_inventory">Rerequesting inventory for [ITEM].</string>
<string name="export_rerequesting_texture">Rerequesting texture [ITEM].</string>
<string name="export_failed_to_load">Failed to load asset [ITEM].</string>
</strings>