diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index e4eda7767..bcbae06ec 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -801,9 +801,7 @@ void LLUUID::generate() #endif if (!has_init) { - // - //if (getNodeID(node_id) <= 0) - // + if (getNodeID(node_id) <= 0) { get_random_bytes(node_id, 6); /* diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index dafed64cc..40bc12b27 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1527,14 +1527,21 @@ bool LLAppViewer::initThreads() void errorCallback(const std::string &error_string) { -#ifndef LL_RELEASE_FOR_DOWNLOAD - OSMessageBox(error_string, "Fatal Error", OSMB_OK); -#endif + static std::string last_message; + if(last_message != error_string) + { + U32 response = OSMessageBox(error_string, "Crash Loop?", OSMB_YESNO); + if(response) + { + last_message = error_string; + return; + } - //Set the ErrorActivated global so we know to create a marker file - gLLErrorActivated = true; - - LLError::crashAndLoop(error_string); + //Set the ErrorActivated global so we know to create a marker file + gLLErrorActivated = true; + + LLError::crashAndLoop(error_string); + } } bool LLAppViewer::initLogging() diff --git a/indra/newview/llfloaterexport.cpp b/indra/newview/llfloaterexport.cpp index d9fa4fa24..8042f4c54 100644 --- a/indra/newview/llfloaterexport.cpp +++ b/indra/newview/llfloaterexport.cpp @@ -16,8 +16,77 @@ #include "llimportobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" +#include "llwindow.h" +#include "llviewerimagelist.h" +#include "lltexturecache.h" +#include "llimage.h" +#include "llappviewer.h" std::vector LLFloaterExport::instances; + +class CacheReadResponder : public LLTextureCache::ReadResponder +{ +public: +CacheReadResponder(const LLUUID& id, LLImageFormatted* image,const std::string& filename) +: mFormattedImage(image), mID(id) +{ + setImage(image); + mFilename = filename; +} +void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) +{ + if(imageformat==IMG_CODEC_TGA && mFormattedImage->getCodec()==IMG_CODEC_J2C) + { + llwarns<<"Bleh its a tga not saving"<getCodec() == imageformat); + mFormattedImage->appendData(data, datasize); + } + else + { + mFormattedImage = LLImageFormatted::createFromType(imageformat); + mFormattedImage->setData(data,datasize); + } + mImageSize = imagesize; + mImageLocal = imagelocal; +} + +virtual void completed(bool success) +{ + if(success && (mFormattedImage.notNull()) && mImageSize>0) + { + + llinfos << "SUCCESS getting texture "<save(mFilename)) + { + llinfos << "FAIL saving texture "< mFormattedImage; + LLUUID mID; + std::string mFilename; +}; + + LLExportable::LLExportable(LLViewerObject* object, std::string name, std::map& primNameMap) : mObject(object), mType(EXPORTABLE_OBJECT), @@ -598,88 +667,143 @@ void LLFloaterExport::onClickSaveAs(void* user_data) if(sd.size()) { std::string default_filename = "untitled"; - - // set correct names within llsd - LLSD::map_iterator map_iter = sd.beginMap(); - LLSD::map_iterator map_end = sd.endMap(); - for( ; map_iter != map_end; ++map_iter) - { - std::istringstream keystr((*map_iter).first); - U32 key; - keystr >> key; - LLSD item = (*map_iter).second; - if(item["type"].asString() == "prim") - { - std::string name = floater->mPrimNameMap[key]; - item["name"] = name; - // I don't understand C++ :( - sd[(*map_iter).first] = item; - } - } - - // count the number of selected items - LLScrollListCtrl* list = floater->getChild("export_list"); - std::vector items = list->getAllData(); - int item_count = 0; - LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID(); - bool all_same_avatarid = true; - std::vector::iterator item_iter = items.begin(); - std::vector::iterator items_end = items.end(); - for( ; item_iter != items_end; ++item_iter) - { - LLScrollListItem* item = (*item_iter); - if(item->getColumn(LIST_CHECKED)->getValue()) - { - item_count++; - if(item->getColumn(LIST_AVATARID)->getValue().asUUID() != avatarid) - { - all_same_avatarid = false; - } - } - } - - if(item_count == 1) - { - // Exporting one item? Use its name for the filename. - // But make sure it's a root! - LLSD target = (*(sd.beginMap())).second; - if(target.has("parent")) - { - std::string parentid = target["parent"].asString(); - target = sd[parentid]; - } - if(target.has("name")) - { - if(target["name"].asString().length() > 0) - { - default_filename = target["name"].asString(); - } - } - } - else - { - // Multiple items? - // If they're all part of the same avatar, use the avatar's name as filename. - if(all_same_avatarid) - { - std::string fullname; - if(gCacheName->getFullName(avatarid, fullname)) - { - default_filename = fullname; - } - } - } - LLFilePicker& file_picker = LLFilePicker::instance(); if(file_picker.getSaveFile( LLFilePicker::FFSAVE_XML, LLDir::getScrubbedFileName(default_filename + ".xml"))) { std::string file_name = file_picker.getFirstFile(); + std::string path = file_name.substr(0,file_name.find_last_of(".")) + "_assets"; + BOOL download_texture = floater->childGetValue("download_textures"); + if(download_texture) + { + if(!LLFile::isdir(path)) + { + LLFile::mkdir(path); + }else + { + U32 response = OSMessageBox("Directory "+path+" already exists, would you like to continue and override files?", "Directory Already Exists", OSMB_YESNO); + if(response) + { + return; + } + } + path.append(gDirUtilp->getDirDelimiter()); //lets add the Delimiter now + } + // set correct names within llsd and download textures + LLSD::map_iterator map_iter = sd.beginMap(); + LLSD::map_iterator map_end = sd.endMap(); + std::list textures; + + for( ; map_iter != map_end; ++map_iter) + { + std::istringstream keystr((*map_iter).first); + U32 key; + keystr >> key; + LLSD item = (*map_iter).second; + if(item["type"].asString() == "prim") + { + std::string name = floater->mPrimNameMap[key]; + item["name"] = name; + // I don't understand C++ :( + sd[(*map_iter).first] = item; + + if(download_texture) + { + //textures + LLSD::array_iterator tex_iter = item["textures"].beginArray(); + for( ; tex_iter != item["textures"].endArray(); ++tex_iter) + { + textures.push_back((*tex_iter)["imageid"].asUUID()); + } + if(item.has("sculpt")) + { + textures.push_back(item["sculpt"]["texture"].asUUID()); + } + } + } + else if(download_texture && item["type"].asString() == "wearable") + { + LLSD::map_iterator tex_iter = item["textures"].beginMap(); + for( ; tex_iter != item["textures"].endMap(); ++tex_iter) + { + textures.push_back((*tex_iter).second.asUUID()); + } + } + } + if(download_texture) + { + textures.unique(); + while(!textures.empty()) + { + llinfos << "Requesting texture " << textures.front().asString() << llendl; + LLViewerImage* img = gImageList.getImage(textures.front(), MIPMAP_TRUE, FALSE); + img->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAX_LEVEL); + + LLImageJ2C * mFormattedImage = new LLImageJ2C; + CacheReadResponder* responder = new CacheReadResponder(textures.front(), mFormattedImage,std::string(path + textures.front().asString() + ".j2c")); + LLAppViewer::getTextureCache()->readFromCache(textures.front(),LLWorkerThread::PRIORITY_HIGH,0,999999,responder); + textures.pop_front(); + } + } + // count the number of selected items + LLScrollListCtrl* list = floater->getChild("export_list"); + std::vector items = list->getAllData(); + int item_count = 0; + LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID(); + bool all_same_avatarid = true; + std::vector::iterator item_iter = items.begin(); + std::vector::iterator items_end = items.end(); + for( ; item_iter != items_end; ++item_iter) + { + LLScrollListItem* item = (*item_iter); + if(item->getColumn(LIST_CHECKED)->getValue()) + { + item_count++; + if(item->getColumn(LIST_AVATARID)->getValue().asUUID() != avatarid) + { + all_same_avatarid = false; + } + } + } + + if(item_count == 1) + { + // Exporting one item? Use its name for the filename. + // But make sure it's a root! + LLSD target = (*(sd.beginMap())).second; + if(target.has("parent")) + { + std::string parentid = target["parent"].asString(); + target = sd[parentid]; + } + if(target.has("name")) + { + if(target["name"].asString().length() > 0) + { + default_filename = target["name"].asString(); + } + } + } + else + { + // Multiple items? + // If they're all part of the same avatar, use the avatar's name as filename. + if(all_same_avatarid) + { + std::string fullname; + if(gCacheName->getFullName(avatarid, fullname)) + { + default_filename = fullname; + } + } + } + llofstream export_file(file_name); LLSDSerialize::toPrettyXML(sd, export_file); export_file.close(); std::string msg = "Saved "; msg.append(file_name); + if(download_texture) msg.append(" (Content might take some time to download)"); LLChat chat(msg); LLFloaterChat::addChat(chat); } @@ -694,6 +818,40 @@ void LLFloaterExport::onClickSaveAs(void* user_data) floater->close(); } +void LLFloaterExport::onFileLoadedForSave(BOOL success, + LLViewerImage *src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata) +{ + if(!userdata){ llinfos << "NULL POINTER" << llendl; return;} + if(final) + { + std::string *temp = static_cast(userdata); + std::string path = *temp; + if( success ) + { + LLPointer image_j2c = new LLImageJ2C(); + if(!image_j2c->encode(src,0.0)) + { + //errorencode + llinfos << "Failed to encode " << path << llendl; + }else if(!image_j2c->save( path )) + { + llinfos << "Failed to write " << path << llendl; + //errorwrite + }else + { + llinfos << "Saved texture " << path << llendl; + //success + } + } + delete temp; + } + +} //static void LLFloaterExport::onClickMakeCopy(void* user_data) diff --git a/indra/newview/llfloaterexport.h b/indra/newview/llfloaterexport.h index e5f1028c5..97fe994a4 100644 --- a/indra/newview/llfloaterexport.h +++ b/indra/newview/llfloaterexport.h @@ -93,6 +93,16 @@ public: static void onClickSelectWearables(void* user_data); static void onClickSaveAs(void* user_data); static void onClickMakeCopy(void* user_data); + + static void onFileLoadedForSave( + BOOL success, + LLViewerImage *src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata ); + private: virtual ~LLFloaterExport(); diff --git a/indra/newview/llfloaterimport.cpp b/indra/newview/llfloaterimport.cpp index e9616f342..b2c248f48 100644 --- a/indra/newview/llfloaterimport.cpp +++ b/indra/newview/llfloaterimport.cpp @@ -150,13 +150,13 @@ void LLFloaterXmlImportOptions::onClickOK(void* user_data) { LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data; LLXmlImportOptions* opt = new LLXmlImportOptions(floaterp->mDefaultOptions); - opt->mRootObjects.clear(); - opt->mChildObjects.clear(); - opt->mWearables.clear(); + opt->clear(); + opt->mReplaceTexture = floaterp->childGetValue("upload_textures"); LLScrollListCtrl* list = floaterp->getChild("import_list"); std::vector items = list->getAllData(); std::vector::iterator item_end = items.end(); std::vector::iterator child_end = floaterp->mDefaultOptions->mChildObjects.end(); + std::list textures; for(std::vector::iterator iter = items.begin(); iter != item_end; ++iter) { if((*iter)->getColumn(LIST_CHECKED)->getValue()) @@ -165,17 +165,47 @@ void LLFloaterXmlImportOptions::onClickOK(void* user_data) if(floaterp->mImportWearableMap.find(id) != floaterp->mImportWearableMap.end()) { opt->mWearables.push_back(floaterp->mImportWearableMap[id]); + if(opt->mReplaceTexture) + std::copy(floaterp->mImportWearableMap[id]->mTextures.begin(),floaterp->mImportWearableMap[id]->mTextures.end(),back_inserter(textures)); } else // object { LLImportObject* objectp = floaterp->mImportObjectMap[id]; + + if(opt->mReplaceTexture) + std::copy(objectp->mTextures.begin(),objectp->mTextures.end(),back_inserter(textures)); + opt->mRootObjects.push_back(objectp); // Add child objects for(std::vector::iterator child_iter = floaterp->mDefaultOptions->mChildObjects.begin(); child_iter != child_end; ++child_iter) { if((*child_iter)->mParentId == objectp->mId) + { + if(opt->mReplaceTexture) + std::copy((*child_iter)->mTextures.begin(),(*child_iter)->mTextures.end(),back_inserter(textures)); opt->mChildObjects.push_back((*child_iter)); + } + } + } + } + } + if(opt->mReplaceTexture) + { + textures.unique(); + if(!opt->mAssetDir.empty() && LLFile::isdir(opt->mAssetDir)) + { + opt->mAssetDir.append(gDirUtilp->getDirDelimiter()); //lets add the Delimiter now + for(std::list::iterator itr = textures.begin(); itr != textures.end(); ++itr) + { + std::string filename = opt->mAssetDir + (*itr).asString() + ".j2c"; + //llinfos << "Looking texture at " << filename << llendl; + if(LLFile::isfile(filename)) + { + //llinfos << "Found texture at " << filename << llendl; + LLImportAssetData* data = new LLImportAssetData(filename,(*itr),LLAssetType::AT_TEXTURE); + + opt->mAssets.push_back(data); } } } @@ -192,16 +222,31 @@ void LLFloaterXmlImportOptions::onClickCancel(void* user_data) } LLFloaterImportProgress::LLFloaterImportProgress() -: LLFloater("ImportProgress", LLRect(0, 100, 400, 0), "Import progress") +: LLFloater("ImportProgress", LLRect(0, 130, 400, 0), "Import progress") { - LLLineEditor* line = new LLLineEditor( + LLLineEditor* line; + LLViewBorder* border; + + line = new LLLineEditor( + std::string("Uploaded"), + LLRect(4, 105, 396, 85), + std::string("Uploaded Assets")); + line->setEnabled(FALSE); + addChild(line); + + border = new LLViewBorder( + "UploadedBorder", + LLRect(4, 104, 395, 85)); + addChild(border); + + line = new LLLineEditor( std::string("Created"), LLRect(4, 80, 396, 60), std::string("Created prims")); line->setEnabled(FALSE); addChild(line); - LLViewBorder* border = new LLViewBorder( + border = new LLViewBorder( "CreatedBorder", LLRect(4, 79, 395, 60)); addChild(border); @@ -256,6 +301,12 @@ void LLFloaterImportProgress::update() { LLFloaterImportProgress* floater = sInstance; + int upload_goal = (int)LLXmlImport::sTotalAssets; + int upload_done = LLXmlImport::sUploadedAssets; + F32 upload_width = F32(390.f / F32(upload_goal)); + upload_width *= F32(upload_done); + bool upload_finished = upload_done >= upload_goal; + int create_goal = (int)LLXmlImport::sPrims.size(); int create_done = create_goal - LLXmlImport::sPrimsNeeded; F32 create_width = F32(390.f / F32(create_goal)); @@ -274,7 +325,7 @@ void LLFloaterImportProgress::update() attach_width *= F32(attach_done); bool attach_finished = attach_done >= attach_goal; - bool all_finished = create_finished && edit_finished && attach_finished; + bool all_finished = upload_finished && create_finished && edit_finished && attach_finished; std::string title; title.assign(all_finished ? "Imported " : "Importing "); @@ -282,16 +333,23 @@ void LLFloaterImportProgress::update() if(!all_finished) title.append("..."); floater->setTitle(title); + std::string uploaded_text = llformat("Uploaded %d/%d assets", S32(upload_done), S32(upload_goal)); std::string created_text = llformat("Created %d/%d prims", S32(create_done), S32(create_goal)); std::string edited_text = llformat("Finished %d/%d prims", edit_done, edit_goal); - LLLineEditor* text = floater->getChild("Created"); + LLLineEditor* text = floater->getChild("Uploaded"); + text->setText(uploaded_text); + + text = floater->getChild("Created"); text->setText(created_text); text = floater->getChild("Edited"); text->setText(edited_text); - LLViewBorder* border = floater->getChild("CreatedBorder"); + LLViewBorder* border = floater->getChild("UploadedBorder"); + border->setRect(LLRect(4, 104, 4 + upload_width, 85)); + + border = floater->getChild("CreatedBorder"); border->setRect(LLRect(4, 79, 4 + create_width, 60)); border = floater->getChild("EditedBorder"); diff --git a/indra/newview/llimportobject.cpp b/indra/newview/llimportobject.cpp index 145f8c435..db5abc3ea 100644 --- a/indra/newview/llimportobject.cpp +++ b/indra/newview/llimportobject.cpp @@ -19,7 +19,10 @@ #include "llscrolllistctrl.h" #include "llviewercontrol.h" #include "llfloaterimport.h" - +#include "llassetuploadresponders.h" +#include "lleconomy.h" +#include "llfloaterperms.h" +#include "llviewerregion.h" // static vars bool LLXmlImport::sImportInProgress = false; @@ -38,6 +41,9 @@ std::map LLXmlImport::sId2localid; std::map LLXmlImport::sRootpositions; std::map LLXmlImport::sRootrotations; LLXmlImportOptions* LLXmlImport::sXmlImportOptions; +std::map LLXmlImport::sTextureReplace; +int LLXmlImport::sTotalAssets = 0; +int LLXmlImport::sUploadedAssets = 0; LLXmlImportOptions::LLXmlImportOptions(LLXmlImportOptions* options) { @@ -47,6 +53,7 @@ LLXmlImportOptions::LLXmlImportOptions(LLXmlImportOptions* options) mWearables = options->mWearables; mSupplier = options->mSupplier; mKeepPosition = options->mKeepPosition; + mAssetDir = options->mAssetDir; } LLXmlImportOptions::LLXmlImportOptions(std::string filename) : mSupplier(NULL), @@ -65,6 +72,7 @@ LLXmlImportOptions::LLXmlImportOptions(std::string filename) llwarns << "Messed up data?" << llendl; return; } + mAssetDir = filename.substr(0,filename.find_last_of(".")) + "_assets"; init(llsd); } LLXmlImportOptions::LLXmlImportOptions(LLSD llsd) @@ -74,12 +82,24 @@ LLXmlImportOptions::LLXmlImportOptions(LLSD llsd) { init(llsd); } - +LLXmlImportOptions::~LLXmlImportOptions() +{ + clear(); +} +void LLXmlImportOptions::clear() +{ + //for_each(mRootObjects.begin(), mRootObjects.end(), DeletePointer()); + mRootObjects.clear(); + //for_each(mChildObjects.begin(), mChildObjects.end(), DeletePointer()); + mChildObjects.clear(); + //for_each(mWearables.begin(), mWearables.end(), DeletePointer()); + mWearables.clear(); + //for_each(mAssets.begin(), mAssets.end(), DeletePointer()); + mAssets.clear(); +} void LLXmlImportOptions::init(LLSD llsd) { - mRootObjects.clear(); - mChildObjects.clear(); - mWearables.clear(); + clear(); // Separate objects and wearables std::vector unsorted_objects; LLSD::map_iterator map_end = llsd.endMap(); @@ -106,7 +126,7 @@ void LLXmlImportOptions::init(LLSD llsd) else mChildObjects.push_back(unsorted_objects[i]); } - + F32 throttle = gSavedSettings.getF32("OutBandwidth"); // Gross magical value that is 128kbit/s // Sim appears to drop requests if they come in faster than this. *sigh* @@ -117,6 +137,149 @@ void LLXmlImportOptions::init(LLSD llsd) gMessageSystem->mPacketRing.setUseOutThrottle(TRUE); } +LLImportAssetData::LLImportAssetData(std::string infilename,LLUUID inassetid,LLAssetType::EType intype) +{ + LLTransactionID _tid; + _tid.generate(); + assetid = _tid.makeAssetID(gAgent.getSecureSessionID()); + tid = _tid; + oldassetid = inassetid; + type = intype; + inv_type = LLInventoryType::defaultForAssetType(type); + name = inassetid.asString(); //use the original asset id as the name + description = ""; + filename = infilename; +} +//We dont need this yet, but its useful to have +/*class LLImportTransferCallback : public LLInventoryCallback +{ +public: + LLImportTransferCallback(LLImportAssetData* data) + { + mData = data; + } + void fire(const LLUUID &inv_item) + { + //add to the inventory inject array and inject after the prim has been made. + } +private: + LLImportAssetData* data; +}; +*/ +class LLImportInventoryResponder : public LLAssetUploadResponder +{ +public: + LLImportInventoryResponder(const LLSD& post_data, + const LLUUID& vfile_id, + LLAssetType::EType asset_type, LLImportAssetData* data) : LLAssetUploadResponder(post_data, vfile_id, asset_type) + { + mData = data; + } + + LLImportInventoryResponder(const LLSD& post_data, const std::string& file_name, + LLAssetType::EType asset_type) : LLAssetUploadResponder(post_data, file_name, asset_type) + { + + } + virtual void uploadComplete(const LLSD& content) + { + llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " << content["new_asset"].asUUID() << " to inventory." << llendl; + //LLPointer cb = new LLImportTransferCallback(mData); + + if(mPostData["folder_id"].asUUID().notNull()) + { + LLPermissions perm; + U32 everyone_perms = PERM_NONE; + U32 group_perms = PERM_NONE; + U32 next_owner_perms = PERM_ALL; + perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + if(content.has("new_next_owner_mask")) + { + // This is a new sim that provides creation perms so use them. + // Do not assume we got the perms we asked for in mPostData + // since the sim may not have granted them all. + everyone_perms = content["new_everyone_mask"].asInteger(); + group_perms = content["new_group_mask"].asInteger(); + next_owner_perms = content["new_next_owner_mask"].asInteger(); + } + else + { + // This old sim doesn't provide creation perms so use old assumption-based perms. + if(mPostData["inventory_type"].asString() != "snapshot") + { + next_owner_perms = PERM_MOVE | PERM_TRANSFER; + } + } + perm.initMasks(PERM_ALL, PERM_ALL, everyone_perms, group_perms, next_owner_perms); + S32 creation_date_now = time_corrected(); + LLPointer item = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), + mPostData["folder_id"].asUUID(), + perm, + content["new_asset"].asUUID(), + mData->type, + mData->inv_type, + mPostData["name"].asString(), + mPostData["description"].asString(), + LLSaleInfo::DEFAULT, + LLInventoryItem::II_FLAGS_NONE, + creation_date_now); + gInventory.updateItem(item); + gInventory.notifyObservers(); + LLXmlImport::sTextureReplace[mData->oldassetid] = content["new_asset"].asUUID(); + } + + LLXmlImport::sUploadedAssets++; + LLFloaterImportProgress::update(); + if(LLXmlImport::sUploadedAssets < LLXmlImport::sTotalAssets) + { + LLImportAssetData* data = LLXmlImport::sXmlImportOptions->mAssets[LLXmlImport::sUploadedAssets]; + data->folderid = mData->folderid; + std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); + if(!url.empty()) + { + LLPointer integrity_test = new LLImageJ2C; + if( !integrity_test->loadAndValidate( data->filename ) ) + { + llinfos << "Image: " << data->filename << " is corrupt." << llendl; + } + S32 file_size; + LLAPRFile infile ; + infile.open(data->filename, LL_APR_RB, LLAPRFile::global, &file_size); + if (infile.getFileHandle()) + { + LLVFile file(gVFS, data->assetid, data->type, LLVFile::WRITE); + file.setMaxSize(file_size); + const S32 buf_size = 65536; + U8 copy_buf[buf_size]; + while ((file_size = infile.read(copy_buf, buf_size))) + { + file.write(copy_buf, file_size); + } + + LLSD body; + body["folder_id"] = data->folderid; + body["asset_type"] = LLAssetType::lookup(data->type); + body["inventory_type"] = LLInventoryType::lookup(data->inv_type); + body["name"] = data->name; + body["description"] = data->description; + body["next_owner_mask"] = LLSD::Integer(U32_MAX); + body["group_mask"] = LLSD::Integer(U32_MAX); + body["everyone_mask"] = LLSD::Integer(U32_MAX); + body["expected_upload_cost"] = LLSD::Integer(LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); + LLHTTPClient::post(url, body, new LLImportInventoryResponder(body, data->assetid, data->type,data)); + } + } + else + llinfos << "NewFileAgentInventory does not exist!!!!" << llendl; + } + else + LLXmlImport::finish_init(); + + + } +private: + LLImportAssetData* mData; +}; std::string terse_F32_string( F32 f ) { @@ -149,6 +312,7 @@ std::string terse_F32_string( F32 f ) LLImportWearable::LLImportWearable(LLSD sd) { + mOrginalLLSD = sd; mName = sd["name"].asString(); mType = sd["wearabletype"].asInteger(); @@ -189,10 +353,59 @@ LLImportWearable::LLImportWearable(LLSD sd) map_end = textures.endMap(); for( ; map_iter != map_end; ++map_iter) { + mTextures.push_back((*map_iter).second); mData += (*map_iter).first + " " + (*map_iter).second.asString() + "\n"; } } +void LLImportWearable::replaceTextures(std::map textures_replace) +{ + LLSD sd = mOrginalLLSD; + mName = sd["name"].asString(); + mType = sd["wearabletype"].asInteger(); + LLSD params = sd["params"]; + LLSD textures = sd["textures"]; + + mData = "LLWearable version 22\n" + + mName + "\n\n" + + "\tpermissions 0\n" + + "\t{\n" + + "\t\tbase_mask\t7fffffff\n" + + "\t\towner_mask\t7fffffff\n" + + "\t\tgroup_mask\t00000000\n" + + "\t\teveryone_mask\t00000000\n" + + "\t\tnext_owner_mask\t00082000\n" + + "\t\tcreator_id\t00000000-0000-0000-0000-000000000000\n" + + "\t\towner_id\t" + gAgent.getID().asString() + "\n" + + "\t\tlast_owner_id\t" + gAgent.getID().asString() + "\n" + + "\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n" + + "\t}\n" + + "\tsale_info\t0\n" + + "\t{\n" + + "\t\tsale_type\tnot\n" + + "\t\tsale_price\t10\n" + + "\t}\n" + + "type " + llformat("%d", mType) + "\n"; + + mData += llformat("parameters %d\n", params.size()); + LLSD::map_iterator map_iter = params.beginMap(); + LLSD::map_iterator map_end = params.endMap(); + for( ; map_iter != map_end; ++map_iter) + { + mData += (*map_iter).first + " " + terse_F32_string((*map_iter).second.asReal()) + "\n"; + } + + mData += llformat("textures %d\n", textures.size()); + map_iter = textures.beginMap(); + map_end = textures.endMap(); + for( ; map_iter != map_end; ++map_iter) + { + LLUUID asset_id = (*map_iter).second.asUUID(); + std::map::iterator iter = textures_replace.find(asset_id); + if(iter != textures_replace.end()) asset_id = (*iter).second; + mData += (*map_iter).first + " " + asset_id.asString() + "\n"; + } +} //LLImportObject::LLImportObject(std::string id, std::string parentId) // : LLViewerObject(LLUUID::null, 9, NULL, TRUE), // mId(id), @@ -268,9 +481,12 @@ LLImportObject::LLImportObject(std::string id, LLSD prim) LLTextureEntry* wat = new LLTextureEntry(); wat->fromLLSD(*array_iter); LLTextureEntry te = *wat; + delete wat; //clean up yo memory + mTextures.push_back(te.getID()); setTE(i, te); i++; } + mTextures.unique(); if(prim.has("name")) { mPrimName = prim["name"].asString(); @@ -440,7 +656,9 @@ void LLXmlImport::import(LLXmlImportOptions* import_options) sImportInProgress = true; sImportHasAttachments = (sId2attachpt.size() > 0); sPrimsNeeded = (int)sPrims.size(); + sTotalAssets = sXmlImportOptions->mAssets.size(); sPrimIndex = 0; + sUploadedAssets = 0; sId2localid.clear(); sRootpositions.clear(); @@ -448,15 +666,70 @@ void LLXmlImport::import(LLXmlImportOptions* import_options) LLFloaterImportProgress::update(); // Create folder - if((sXmlImportOptions->mWearables.size() > 0) || (sId2attachpt.size() > 0)) + if((sXmlImportOptions->mWearables.size() > 0) || (sId2attachpt.size() > 0) || (sTotalAssets > 0)) { sFolderID = gInventory.createNewCategory( gAgent.getInventoryRootID(), LLAssetType::AT_NONE, sXmlImportOptions->mName); } + if(sXmlImportOptions->mReplaceTexture && sTotalAssets > 0 && !sXmlImportOptions->mAssetDir.empty()) + { + LLUUID folder_id = gInventory.createNewCategory( sFolderID, LLAssetType::AT_NONE, "Textures"); + //starting up the texture uploading + LLImportAssetData* data = sXmlImportOptions->mAssets[0]; + data->folderid = folder_id; + sTextureReplace[data->oldassetid] = data->assetid; + std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); + if(!url.empty()) + { + LLPointer integrity_test = new LLImageJ2C; + if( !integrity_test->loadAndValidate( data->filename ) ) + { + llinfos << "Image: " << data->filename << " is corrupt." << llendl; + } + S32 file_size; + LLAPRFile infile ; + infile.open(data->filename, LL_APR_RB, LLAPRFile::global, &file_size); + if (infile.getFileHandle()) + { + LLVFile file(gVFS, data->assetid, data->type, LLVFile::WRITE); + file.setMaxSize(file_size); + const S32 buf_size = 65536; + U8 copy_buf[buf_size]; + while ((file_size = infile.read(copy_buf, buf_size))) + { + file.write(copy_buf, file_size); + } + LLSD body; + body["folder_id"] = folder_id; + body["asset_type"] = LLAssetType::lookup(data->type); + body["inventory_type"] = LLInventoryType::lookup(data->inv_type); + body["name"] = data->name; + body["description"] = data->description; + body["next_owner_mask"] = LLSD::Integer(U32_MAX); + body["group_mask"] = LLSD::Integer(U32_MAX); + body["everyone_mask"] = LLSD::Integer(U32_MAX); + body["expected_upload_cost"] = LLSD::Integer(LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); + LLHTTPClient::post(url, body, new LLImportInventoryResponder(body, data->assetid, data->type,data)); + } + } + else + { + //maybe do legacy upload here????? + llinfos << "NewFileAgentInventory does not exist!!!!" << llendl; + LLXmlImport::finish_init(); + } + } + else + LLXmlImport::finish_init(); +} + +void LLXmlImport::finish_init() +{ // Go ahead and upload wearables int num_wearables = sXmlImportOptions->mWearables.size(); for(int i = 0; i < num_wearables; i++) { + sXmlImportOptions->mWearables[i]->replaceTextures(sTextureReplace); //hack for importing weable textures LLAssetType::EType at = LLAssetType::AT_CLOTHING; if(sXmlImportOptions->mWearables[i]->mType < 4) at = LLAssetType::AT_BODYPART; LLUUID tid; @@ -487,10 +760,9 @@ void LLXmlImport::import(LLXmlImportOptions* import_options) gMessageSystem->addStringFast(_PREHASH_Description, ""); gMessageSystem->sendReliable(gAgent.getRegionHost()); } - + // Go ahead and upload asset data rez_supply(); } - // static void LLXmlImport::onNewPrim(LLViewerObject* object) { @@ -577,6 +849,8 @@ void LLXmlImport::onNewPrim(LLViewerObject* object) if (from->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) { LLSculptParams sculpt = *((LLSculptParams*)from->getParameterEntry(LLNetworkData::PARAMS_SCULPT)); + if(sXmlImportOptions->mReplaceTexture && sTextureReplace.find(sculpt.getSculptTexture()) != sTextureReplace.end()) + sculpt.setSculptTexture(sTextureReplace[sculpt.getSculptTexture()]); object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt, true); object->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, true); object->parameterChanged(LLNetworkData::PARAMS_SCULPT, true); @@ -593,6 +867,8 @@ void LLXmlImport::onNewPrim(LLViewerObject* object) { const LLTextureEntry* wat = from->getTE(i); LLTextureEntry te = *wat; + if(sXmlImportOptions->mReplaceTexture && sTextureReplace.find(te.getID()) != sTextureReplace.end()) + te.setID(sTextureReplace[te.getID()]); object->setTE(i, te); } object->sendTEUpdate(); diff --git a/indra/newview/llimportobject.h b/indra/newview/llimportobject.h index 1e1e8897c..1da236cae 100644 --- a/indra/newview/llimportobject.h +++ b/indra/newview/llimportobject.h @@ -8,7 +8,24 @@ #include "llviewerobject.h" #include "llfloater.h" +#include "llvoavatardefines.h" +class LLImportAssetData +{ +public: + LLImportAssetData(std::string infilename,LLUUID inassetid,LLAssetType::EType intype); + U32 localid; + LLAssetType::EType type; + LLInventoryType::EType inv_type; + EWearableType wear_type; + LLTransactionID tid; + LLUUID assetid; + LLUUID folderid; + LLUUID oldassetid; + std::string name; + std::string description; + std::string filename; +}; class LLImportWearable { @@ -16,8 +33,10 @@ public: std::string mName; int mType; std::string mData; - + LLSD mOrginalLLSD; LLImportWearable(LLSD sd); + std::list mTextures; + void replaceTextures(std::map textures_replace); }; class LLImportObject : public LLViewerObject @@ -25,7 +44,6 @@ class LLImportObject : public LLViewerObject public: //LLImportObject(std::string id, std::string parentId); LLImportObject(std::string id, LLSD prim); - std::string mId; std::string mParentId; std::string mPrimName; @@ -33,23 +51,28 @@ public: U32 importAttachPoint; LLVector3 importAttachPos; LLQuaternion importAttachRot; + std::list mTextures; }; - class LLXmlImportOptions { public: LLXmlImportOptions(LLXmlImportOptions* options); LLXmlImportOptions(std::string filename); LLXmlImportOptions(LLSD llsd); + virtual ~LLXmlImportOptions(); + void clear(); void init(LLSD llsd); std::string mName; //LLSD mLLSD; + std::string mAssetDir; + std::vector mAssets; std::vector mRootObjects; std::vector mChildObjects; std::vector mWearables; BOOL mKeepPosition; LLViewerObject* mSupplier; + BOOL mReplaceTexture; }; @@ -62,6 +85,7 @@ public: static void onNewAttachment(LLViewerObject* object); static void Cancel(void* user_data); static void rez_supply(); + static void finish_init(); static bool sImportInProgress; static bool sImportHasAttachments; @@ -79,6 +103,10 @@ public: static std::map sRootpositions; static std::map sRootrotations; static LLXmlImportOptions* sXmlImportOptions; + + static int sTotalAssets; + static int sUploadedAssets; + static std::map sTextureReplace; }; #endif diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 397cdef85..fc28effbc 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -55,14 +55,14 @@ #include "llviewerwindow.h" #include "llappviewer.h" #include "lluploaddialog.h" -// -#include "llselectmgr.h" -#include "llfloaterimport.h" -#include "llfloaterexport.h" -#include "llassettype.h" -#include "llinventorytype.h" -#include "llbvhloader.h" -// +// +#include "llselectmgr.h" +#include "llfloaterimport.h" +#include "llfloaterexport.h" +#include "llassettype.h" +#include "llinventorytype.h" +#include "llbvhloader.h" +// // linden libraries @@ -241,9 +241,9 @@ const std::string upload_pick(void* data) //now we check to see //if the file is actually a valid image/sound/etc. - // Screw their checks - /* - // + // Screw their checks + /* + // if (type == LLFilePicker::FFLOAD_WAV) { // pre-qualify wavs to make sure the format is acceptable @@ -257,9 +257,9 @@ const std::string upload_pick(void* data) return std::string(); } }//end if a wave/sound file - // - */ - // + // + */ + // return filename; @@ -330,12 +330,12 @@ class LLFileUploadBulk : public view_listener_t LLFilePicker& picker = LLFilePicker::instance(); if (picker.getMultipleOpenFiles()) { - // - //const std::string& filename = picker.getFirstFile(); - std::string filename; - while(!(filename = picker.getNextFile()).empty()) - { - // + // + //const std::string& filename = picker.getFirstFile(); + std::string filename; + while(!(filename = picker.getNextFile()).empty()) + { + // std::string name = gDirUtilp->getBaseFileName(filename, true); std::string asset_name = name; @@ -356,7 +356,7 @@ class LLFileUploadBulk : public view_listener_t // *NOTE: Ew, we don't iterate over the file list here, // we handle the next files in upload_done_callback() // not anymore! - } + } } else { @@ -366,33 +366,33 @@ class LLFileUploadBulk : public view_listener_t } }; -// -class LLFileImportXML : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(LLFilePicker::FFLOAD_XML)) - { - return true; - } - std::string file_name = picker.getFirstFile(); - new LLFloaterXmlImportOptions(new LLXmlImportOptions(file_name)); - return true; - } -}; - -class LLFileEnableImportXML : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - bool new_value = !LLXmlImport::sImportInProgress; - - // horrendously opaque, this code - gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); - return true; - } -}; +// +class LLFileImportXML : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getOpenFile(LLFilePicker::FFLOAD_XML)) + { + return true; + } + std::string file_name = picker.getFirstFile(); + new LLFloaterXmlImportOptions(new LLXmlImportOptions(file_name)); + return true; + } +}; + +class LLFileEnableImportXML : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool new_value = !LLXmlImport::sImportInProgress; + + // horrendously opaque, this code + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; // void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args) @@ -449,15 +449,15 @@ class LLFileCloseAllWindows : public view_listener_t } }; -// -class LLFileMinimizeAllWindows : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - gFloaterView->minimizeAllChildren(); - return true; - } -}; +// +class LLFileMinimizeAllWindows : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + gFloaterView->minimizeAllChildren(); + return true; + } +}; // class LLFileSaveTexture : public view_listener_t @@ -467,20 +467,20 @@ class LLFileSaveTexture : public view_listener_t LLFloater* top = gFloaterView->getFrontmost(); if (top) { - // - if(top->canSaveAs()) - { - // + // + if(top->canSaveAs()) + { + // top->saveAs(); - // - return true; + // + return true; } - // - } - // - top = new LLFloaterExport(); - top->center(); - // + // + } + // + top = new LLFloaterExport(); + top->center(); + // return true; } }; @@ -722,13 +722,13 @@ void upload_new_resource(const std::string& src_filename, std::string name, return; } } - // - else if(exten == "ogg") - { - asset_type = LLAssetType::AT_SOUND; // tag it as audio - filename = src_filename; - } - // + // + else if(exten == "ogg") + { + asset_type = LLAssetType::AT_SOUND; // tag it as audio + filename = src_filename; + } + // else if(exten == "tmp") { // This is a generic .lin resource file @@ -848,83 +848,83 @@ void upload_new_resource(const std::string& src_filename, std::string name, } else if (exten == "bvh") { - // THE FUCK WE DON'T - //error_message = llformat("We do not currently support bulk upload of animation files\n"); - //upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); - //return; - asset_type = LLAssetType::AT_ANIMATION; + // THE FUCK WE DON'T + //error_message = llformat("We do not currently support bulk upload of animation files\n"); + //upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); + //return; + asset_type = LLAssetType::AT_ANIMATION; S32 file_size; - LLAPRFile fp; + LLAPRFile fp; - if(!fp.open(src_filename, LL_APR_RB, LLAPRFile::local, &file_size)) - { - args["ERROR_MESSAGE"] = llformat("Couldn't read file %s\n", src_filename.c_str()); - LLNotifications::instance().add("ErrorMessage", args); - return; - } - char* file_buffer = new char[file_size + 1]; - if(!fp.read(file_buffer, file_size)) - { - fp.close(); - delete[] file_buffer; - args["ERROR_MESSAGE"] = llformat("Couldn't read file %s\n", src_filename.c_str()); - LLNotifications::instance().add("ErrorMessage", args); - return; - } - LLBVHLoader* loaderp = new LLBVHLoader(file_buffer); - if(!loaderp->isInitialized()) - { - fp.close(); - delete[] file_buffer; - args["ERROR_MESSAGE"] = llformat("Couldn't convert file %s to internal animation format\n", src_filename.c_str()); - LLNotifications::instance().add("ErrorMessage", args); - return; - } - S32 buffer_size = loaderp->getOutputSize(); - U8* buffer = new U8[buffer_size]; - LLDataPackerBinaryBuffer dp(buffer, buffer_size); - loaderp->serialize(dp); + if(!fp.open(src_filename, LL_APR_RB, LLAPRFile::local, &file_size)) + { + args["ERROR_MESSAGE"] = llformat("Couldn't read file %s\n", src_filename.c_str()); + LLNotifications::instance().add("ErrorMessage", args); + return; + } + char* file_buffer = new char[file_size + 1]; + if(!fp.read(file_buffer, file_size)) + { + fp.close(); + delete[] file_buffer; + args["ERROR_MESSAGE"] = llformat("Couldn't read file %s\n", src_filename.c_str()); + LLNotifications::instance().add("ErrorMessage", args); + return; + } + LLBVHLoader* loaderp = new LLBVHLoader(file_buffer); + if(!loaderp->isInitialized()) + { + fp.close(); + delete[] file_buffer; + args["ERROR_MESSAGE"] = llformat("Couldn't convert file %s to internal animation format\n", src_filename.c_str()); + LLNotifications::instance().add("ErrorMessage", args); + return; + } + S32 buffer_size = loaderp->getOutputSize(); + U8* buffer = new U8[buffer_size]; + LLDataPackerBinaryBuffer dp(buffer, buffer_size); + loaderp->serialize(dp); LLAPRFile apr_file; - apr_file.open(filename, LL_APR_WB, LLAPRFile::local); - apr_file.write(buffer, buffer_size); - delete[] file_buffer; - delete[] buffer; - fp.close(); - apr_file.close(); - // - } - // - else if (exten == "animatn") - { - asset_type = LLAssetType::AT_ANIMATION; - filename = src_filename; - } - else if(exten == "jp2" || exten == "j2k" || exten == "j2c") - { - asset_type = LLAssetType::AT_TEXTURE; - filename = src_filename; - } - else if(exten == "gesture") - { - asset_type = LLAssetType::AT_GESTURE; - filename = src_filename; - } - else if(exten == "notecard") - { - asset_type = LLAssetType::AT_NOTECARD; - filename = src_filename; - } - else if(exten == "lsl") - { - asset_type = LLAssetType::AT_LSL_TEXT; - filename = src_filename; - } - else if(exten == "eyes" || exten == "gloves" || exten == "hair" || exten == "jacket" || exten == "pants" || exten == "shape" || exten == "shirt" || exten == "shoes" || exten == "skin" || exten == "skirt" || exten == "socks" || exten == "underpants" || exten == "undershirt" || exten == "bodypart" || exten == "clothing") - { - asset_type = LLAssetType::AT_CLOTHING; - filename = src_filename; - } - // + apr_file.open(filename, LL_APR_WB, LLAPRFile::local); + apr_file.write(buffer, buffer_size); + delete[] file_buffer; + delete[] buffer; + fp.close(); + apr_file.close(); + // + } + // + else if (exten == "animatn") + { + asset_type = LLAssetType::AT_ANIMATION; + filename = src_filename; + } + else if(exten == "jp2" || exten == "j2k" || exten == "j2c") + { + asset_type = LLAssetType::AT_TEXTURE; + filename = src_filename; + } + else if(exten == "gesture") + { + asset_type = LLAssetType::AT_GESTURE; + filename = src_filename; + } + else if(exten == "notecard") + { + asset_type = LLAssetType::AT_NOTECARD; + filename = src_filename; + } + else if(exten == "lsl") + { + asset_type = LLAssetType::AT_LSL_TEXT; + filename = src_filename; + } + else if(exten == "eyes" || exten == "gloves" || exten == "hair" || exten == "jacket" || exten == "pants" || exten == "shape" || exten == "shirt" || exten == "shoes" || exten == "skin" || exten == "skirt" || exten == "socks" || exten == "underpants" || exten == "undershirt" || exten == "bodypart" || exten == "clothing") + { + asset_type = LLAssetType::AT_CLOTHING; + filename = src_filename; + } + // else { // Unknown extension @@ -970,27 +970,27 @@ void upload_new_resource(const std::string& src_filename, std::string name, { t_disp_name = src_filename; } - // hack to create scripts and gestures - if(exten == "lsl" || exten == "gesture" || exten == "notecard") // added notecard Oct 15 2009 - { - LLInventoryType::EType inv_type = LLInventoryType::IT_GESTURE; - if(exten == "lsl") inv_type = LLInventoryType::IT_LSL; - else if(exten == "gesture") inv_type = LLInventoryType::IT_GESTURE; - else if(exten == "notecard") inv_type = LLInventoryType::IT_NOTECARD; - create_inventory_item( gAgent.getID(), - gAgent.getSessionID(), - gInventory.findCategoryUUIDForType(asset_type), - LLTransactionID::tnull, - name, - uuid.asString(), // fake asset id, but in vfs - asset_type, - inv_type, - NOT_WEARABLE, - PERM_ITEM_UNRESTRICTED, - new NewResourceItemCallback); - } - else - // + // hack to create scripts and gestures + if(exten == "lsl" || exten == "gesture" || exten == "notecard") // added notecard Oct 15 2009 + { + LLInventoryType::EType inv_type = LLInventoryType::IT_GESTURE; + if(exten == "lsl") inv_type = LLInventoryType::IT_LSL; + else if(exten == "gesture") inv_type = LLInventoryType::IT_GESTURE; + else if(exten == "notecard") inv_type = LLInventoryType::IT_NOTECARD; + create_inventory_item( gAgent.getID(), + gAgent.getSessionID(), + gInventory.findCategoryUUIDForType(asset_type), + LLTransactionID::tnull, + name, + uuid.asString(), // fake asset id, but in vfs + asset_type, + inv_type, + NOT_WEARABLE, + PERM_ITEM_UNRESTRICTED, + new NewResourceItemCallback); + } + else + // upload_new_resource(tid, asset_type, name, desc, compression_info, // tid destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms, display_name, callback, expected_upload_cost, userdata); @@ -1008,7 +1008,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, LLFilePicker::instance().reset(); } } - + void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed) { LLResourceData* data = (LLResourceData*)user_data; @@ -1095,9 +1095,9 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt LLUploadDialog::modalUploadFinished(); delete data; - // - /* - // + // + /* + // // *NOTE: This is a pretty big hack. What this does is check the // file picker if there are any more pending uploads. If so, // upload that file. @@ -1121,8 +1121,8 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost userdata); } - // - */ + // + */ // } @@ -1260,16 +1260,16 @@ void init_menu_file() (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound"); (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim"); (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk"); - // - (new LLFileImportXML())->registerListener(gMenuHolder, "File.ImportXML"); - (new LLFileEnableImportXML())->registerListener(gMenuHolder, "File.EnableImportXML"); - // + // + (new LLFileImportXML())->registerListener(gMenuHolder, "File.ImportXML"); + (new LLFileEnableImportXML())->registerListener(gMenuHolder, "File.EnableImportXML"); + // (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow"); (new LLFileCloseAllWindows())->registerListener(gMenuHolder, "File.CloseAllWindows"); (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow"); (new LLFileEnableCloseAllWindows())->registerListener(gMenuHolder, "File.EnableCloseAllWindows"); - // - (new LLFileMinimizeAllWindows())->registerListener(gMenuHolder, "File.MinimizeAllWindows"); + // + (new LLFileMinimizeAllWindows())->registerListener(gMenuHolder, "File.MinimizeAllWindows"); // (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture"); (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot"); diff --git a/indra/newview/skins/default/xui/en-us/floater_export.xml b/indra/newview/skins/default/xui/en-us/floater_export.xml index 9e6190d91..cf9e1d181 100644 --- a/indra/newview/skins/default/xui/en-us/floater_export.xml +++ b/indra/newview/skins/default/xui/en-us/floater_export.xml @@ -19,6 +19,7 @@ left_delta="66" name="select_wearables_btn" width="80" /> +