diff --git a/indra/newview/fsexport.cpp b/indra/newview/fsexport.cpp index a71b631834..2194065fd6 100644 --- a/indra/newview/fsexport.cpp +++ b/indra/newview/fsexport.cpp @@ -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 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 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("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("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(); + } +} diff --git a/indra/newview/fsexport.h b/indra/newview/fsexport.h index 7f9d4c2b11..d6960bb815 100644 --- a/indra/newview/fsexport.h +++ b/indra/newview/fsexport.h @@ -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 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 diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 4919ec23a3..e3d92d2ee4 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -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); LLFloaterReg::add("fs_group", "floater_fs_group.xml",&LLFloaterReg::build); LLFloaterReg::add("fs_group_titles", "floater_fs_group_titles.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_export", "floater_fs_export.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_import", "floater_fs_import.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_posestand", "floater_fs_posestand.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_placedetails", "floater_fs_placedetails.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/skins/default/xui/en/floater_fs_export.xml b/indra/newview/skins/default/xui/en/floater_fs_export.xml new file mode 100644 index 0000000000..f66a061573 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_fs_export.xml @@ -0,0 +1,32 @@ + + + +