Object textures can now be export and import
This commit is contained in:
@@ -801,9 +801,7 @@ void LLUUID::generate()
|
||||
#endif
|
||||
if (!has_init)
|
||||
{
|
||||
// <edit>
|
||||
//if (getNodeID(node_id) <= 0)
|
||||
// </edit>
|
||||
if (getNodeID(node_id) <= 0)
|
||||
{
|
||||
get_random_bytes(node_id, 6);
|
||||
/*
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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*> 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"<<llendl;
|
||||
mFormattedImage=NULL;
|
||||
mImageSize=0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFormattedImage.notNull())
|
||||
{
|
||||
llassert_always(mFormattedImage->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 "<<mID<< llendl;
|
||||
|
||||
llinfos << "Saving to "<< mFilename<<llendl;
|
||||
|
||||
if(!mFormattedImage->save(mFilename))
|
||||
{
|
||||
llinfos << "FAIL saving texture "<<mID<< llendl;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!success)
|
||||
llwarns << "FAIL NOT SUCCESSFUL getting texture "<<mID<< llendl;
|
||||
if(mFormattedImage.isNull())
|
||||
llwarns << "FAIL image is NULL "<<mID<< llendl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
LLUUID mID;
|
||||
std::string mFilename;
|
||||
};
|
||||
|
||||
|
||||
LLExportable::LLExportable(LLViewerObject* object, std::string name, std::map<U32,std::string>& 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<LLScrollListCtrl>("export_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
int item_count = 0;
|
||||
LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID();
|
||||
bool all_same_avatarid = true;
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::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<LLUUID> 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<LLScrollListCtrl>("export_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
int item_count = 0;
|
||||
LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID();
|
||||
bool all_same_avatarid = true;
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::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<std::string*>(userdata);
|
||||
std::string path = *temp;
|
||||
if( success )
|
||||
{
|
||||
LLPointer<LLImageJ2C> 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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<LLScrollListCtrl>("import_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator item_end = items.end();
|
||||
std::vector<LLImportObject*>::iterator child_end = floaterp->mDefaultOptions->mChildObjects.end();
|
||||
std::list<LLUUID> textures;
|
||||
for(std::vector<LLScrollListItem*>::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<LLImportObject*>::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<LLUUID>::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<LLLineEditor>("Created");
|
||||
LLLineEditor* text = floater->getChild<LLLineEditor>("Uploaded");
|
||||
text->setText(uploaded_text);
|
||||
|
||||
text = floater->getChild<LLLineEditor>("Created");
|
||||
text->setText(created_text);
|
||||
|
||||
text = floater->getChild<LLLineEditor>("Edited");
|
||||
text->setText(edited_text);
|
||||
|
||||
LLViewBorder* border = floater->getChild<LLViewBorder>("CreatedBorder");
|
||||
LLViewBorder* border = floater->getChild<LLViewBorder>("UploadedBorder");
|
||||
border->setRect(LLRect(4, 104, 4 + upload_width, 85));
|
||||
|
||||
border = floater->getChild<LLViewBorder>("CreatedBorder");
|
||||
border->setRect(LLRect(4, 79, 4 + create_width, 60));
|
||||
|
||||
border = floater->getChild<LLViewBorder>("EditedBorder");
|
||||
|
||||
@@ -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<std::string, U32> LLXmlImport::sId2localid;
|
||||
std::map<U32, LLVector3> LLXmlImport::sRootpositions;
|
||||
std::map<U32, LLQuaternion> LLXmlImport::sRootrotations;
|
||||
LLXmlImportOptions* LLXmlImport::sXmlImportOptions;
|
||||
std::map<LLUUID,LLUUID> 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<LLImportObject*> 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<LLInventoryCallback> 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<LLViewerInventoryItem> 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<LLImageJ2C> 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<LLUUID,LLUUID> 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<LLUUID,LLUUID>::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<LLImageJ2C> 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();
|
||||
|
||||
@@ -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<LLUUID> mTextures;
|
||||
void replaceTextures(std::map<LLUUID,LLUUID> 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<LLUUID> 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<LLImportAssetData*> mAssets;
|
||||
std::vector<LLImportObject*> mRootObjects;
|
||||
std::vector<LLImportObject*> mChildObjects;
|
||||
std::vector<LLImportWearable*> 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<U32, LLVector3> sRootpositions;
|
||||
static std::map<U32, LLQuaternion> sRootrotations;
|
||||
static LLXmlImportOptions* sXmlImportOptions;
|
||||
|
||||
static int sTotalAssets;
|
||||
static int sUploadedAssets;
|
||||
static std::map<LLUUID,LLUUID> sTextureReplace;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -55,14 +55,14 @@
|
||||
#include "llviewerwindow.h"
|
||||
#include "llappviewer.h"
|
||||
#include "lluploaddialog.h"
|
||||
// <edit>
|
||||
#include "llselectmgr.h"
|
||||
#include "llfloaterimport.h"
|
||||
#include "llfloaterexport.h"
|
||||
#include "llassettype.h"
|
||||
#include "llinventorytype.h"
|
||||
#include "llbvhloader.h"
|
||||
// </edit>
|
||||
// <edit>
|
||||
#include "llselectmgr.h"
|
||||
#include "llfloaterimport.h"
|
||||
#include "llfloaterexport.h"
|
||||
#include "llassettype.h"
|
||||
#include "llinventorytype.h"
|
||||
#include "llbvhloader.h"
|
||||
// </edit>
|
||||
|
||||
|
||||
// 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.
|
||||
// <edit> Screw their checks
|
||||
/*
|
||||
// </edit>
|
||||
// <edit> Screw their checks
|
||||
/*
|
||||
// </edit>
|
||||
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
|
||||
// <edit>
|
||||
*/
|
||||
// </edit>
|
||||
// <edit>
|
||||
*/
|
||||
// </edit>
|
||||
|
||||
|
||||
return filename;
|
||||
@@ -330,12 +330,12 @@ class LLFileUploadBulk : public view_listener_t
|
||||
LLFilePicker& picker = LLFilePicker::instance();
|
||||
if (picker.getMultipleOpenFiles())
|
||||
{
|
||||
// <edit>
|
||||
//const std::string& filename = picker.getFirstFile();
|
||||
std::string filename;
|
||||
while(!(filename = picker.getNextFile()).empty())
|
||||
{
|
||||
// </edit>
|
||||
// <edit>
|
||||
//const std::string& filename = picker.getFirstFile();
|
||||
std::string filename;
|
||||
while(!(filename = picker.getNextFile()).empty())
|
||||
{
|
||||
// </edit>
|
||||
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()
|
||||
// </edit> not anymore!
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -366,33 +366,33 @@ class LLFileUploadBulk : public view_listener_t
|
||||
}
|
||||
};
|
||||
|
||||
// <edit>
|
||||
class LLFileImportXML : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> 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<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
bool new_value = !LLXmlImport::sImportInProgress;
|
||||
|
||||
// horrendously opaque, this code
|
||||
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// <edit>
|
||||
class LLFileImportXML : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> 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<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
bool new_value = !LLXmlImport::sImportInProgress;
|
||||
|
||||
// horrendously opaque, this code
|
||||
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// </edit>
|
||||
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
// <edit>
|
||||
class LLFileMinimizeAllWindows : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
gFloaterView->minimizeAllChildren();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// <edit>
|
||||
class LLFileMinimizeAllWindows : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
gFloaterView->minimizeAllChildren();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// </edit>
|
||||
|
||||
class LLFileSaveTexture : public view_listener_t
|
||||
@@ -467,20 +467,20 @@ class LLFileSaveTexture : public view_listener_t
|
||||
LLFloater* top = gFloaterView->getFrontmost();
|
||||
if (top)
|
||||
{
|
||||
// <edit>
|
||||
if(top->canSaveAs())
|
||||
{
|
||||
// </edit>
|
||||
// <edit>
|
||||
if(top->canSaveAs())
|
||||
{
|
||||
// </edit>
|
||||
top->saveAs();
|
||||
// <edit>
|
||||
return true;
|
||||
// <edit>
|
||||
return true;
|
||||
}
|
||||
// </edit>
|
||||
}
|
||||
// <edit>
|
||||
top = new LLFloaterExport();
|
||||
top->center();
|
||||
// </edit>
|
||||
// </edit>
|
||||
}
|
||||
// <edit>
|
||||
top = new LLFloaterExport();
|
||||
top->center();
|
||||
// </edit>
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -722,13 +722,13 @@ void upload_new_resource(const std::string& src_filename, std::string name,
|
||||
return;
|
||||
}
|
||||
}
|
||||
// <edit>
|
||||
else if(exten == "ogg")
|
||||
{
|
||||
asset_type = LLAssetType::AT_SOUND; // tag it as audio
|
||||
filename = src_filename;
|
||||
}
|
||||
// </edit>
|
||||
// <edit>
|
||||
else if(exten == "ogg")
|
||||
{
|
||||
asset_type = LLAssetType::AT_SOUND; // tag it as audio
|
||||
filename = src_filename;
|
||||
}
|
||||
// </edit>
|
||||
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")
|
||||
{
|
||||
// <edit> 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;
|
||||
// <edit> 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();
|
||||
// </edit>
|
||||
}
|
||||
// <edit>
|
||||
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;
|
||||
}
|
||||
// </edit>
|
||||
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();
|
||||
// </edit>
|
||||
}
|
||||
// <edit>
|
||||
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;
|
||||
}
|
||||
// </edit>
|
||||
else
|
||||
{
|
||||
// Unknown extension
|
||||
@@ -970,27 +970,27 @@ void upload_new_resource(const std::string& src_filename, std::string name,
|
||||
{
|
||||
t_disp_name = src_filename;
|
||||
}
|
||||
// <edit> 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
|
||||
// </edit>
|
||||
// <edit> 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
|
||||
// </edit>
|
||||
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;
|
||||
|
||||
// <edit>
|
||||
/*
|
||||
// </edit>
|
||||
// <edit>
|
||||
/*
|
||||
// </edit>
|
||||
// *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);
|
||||
}
|
||||
// <edit>
|
||||
*/
|
||||
// <edit>
|
||||
*/
|
||||
// </edit>
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
// <edit>
|
||||
(new LLFileImportXML())->registerListener(gMenuHolder, "File.ImportXML");
|
||||
(new LLFileEnableImportXML())->registerListener(gMenuHolder, "File.EnableImportXML");
|
||||
// </edit>
|
||||
// <edit>
|
||||
(new LLFileImportXML())->registerListener(gMenuHolder, "File.ImportXML");
|
||||
(new LLFileEnableImportXML())->registerListener(gMenuHolder, "File.EnableImportXML");
|
||||
// </edit>
|
||||
(new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow");
|
||||
(new LLFileCloseAllWindows())->registerListener(gMenuHolder, "File.CloseAllWindows");
|
||||
(new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow");
|
||||
(new LLFileEnableCloseAllWindows())->registerListener(gMenuHolder, "File.EnableCloseAllWindows");
|
||||
// <edit>
|
||||
(new LLFileMinimizeAllWindows())->registerListener(gMenuHolder, "File.MinimizeAllWindows");
|
||||
// <edit>
|
||||
(new LLFileMinimizeAllWindows())->registerListener(gMenuHolder, "File.MinimizeAllWindows");
|
||||
// </edit>
|
||||
(new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture");
|
||||
(new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot");
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
left_delta="66" name="select_wearables_btn" width="80" />
|
||||
|
||||
<text bottom="25" left="10" width="250" height="20" name="names_progress_text"></text>
|
||||
<check_box bottom="28" left="186" width="250" height="20" name="download_textures" label="Download Textures" initial_value="false"/>
|
||||
|
||||
<button bottom="8" follows="bottom|left" height="20" label="Save As..."
|
||||
left="10" width="142" name="save_as_btn" />
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
left_delta="66" name="select_wearables_btn" width="80" />
|
||||
|
||||
<check_box bottom="28" left="10" width="250" height="20" name="keep_position_check" label="Use previous region position" initial_value="false"/>
|
||||
<check_box bottom="28" left="186" width="250" height="20" name="upload_textures" label="Upload Textures" initial_value="false"/>
|
||||
|
||||
<button bottom="8" follows="bottom|left" height="20" label="OK"
|
||||
left="10" width="142" name="ok_btn" />
|
||||
|
||||
Reference in New Issue
Block a user