Files
SingularityViewer/indra/newview/llfloaterexport.cpp
Shyotl e756140e1d Innitial commit of experimental v2 texture system port work. Compiles and runs on windows, at least. Fixing bugs as they come.
Need to test:
localassetbrowser
preview related floaters
hgfloatertexteditor
maps
media textures! Currently very hacky
web browser
alpha masks on avatars
bumpmaps
Are all sky components appearing?
LLViewerDynamicTexture (texture baking, browser, animated textures, anim previews, etc)
Snapshot related features
Customize avatar
vfs floater
UI textures in general
Texture priority issues
2011-03-31 03:22:01 -05:00

907 lines
26 KiB
C++

// <edit>
#include "llviewerprecompiledheaders.h"
#include "llfloaterexport.h"
#include "lluictrlfactory.h"
#include "llsdutil.h"
#include "llsdutil_math.h"
#include "llsdserialize.h"
#include "llselectmgr.h"
#include "llscrolllistctrl.h"
#include "llchat.h"
#include "llfloaterchat.h"
#include "llfilepicker.h"
#include "llagent.h"
#include "llvoavatar.h"
#include "llvoavatardefines.h"
#include "llimportobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llwindow.h"
#include "llviewertexturelist.h"
#include "lltexturecache.h"
#include "llimage.h"
#include "llappviewer.h"
#include "llimagej2c.h"
std::vector<LLFloaterExport*> LLFloaterExport::instances;
class CacheReadResponder : public LLTextureCache::ReadResponder
{
public:
CacheReadResponder(const LLUUID& id, const std::string& filename)
: mID(id)
{
mFormattedImage = new LLImageJ2C;
setImage(mFormattedImage);
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),
mPrimNameMap(&primNameMap)
{
}
LLExportable::LLExportable(LLVOAvatar* avatar, EWearableType type, std::map<U32,std::string>& primNameMap)
: mAvatar(avatar),
mType(EXPORTABLE_WEARABLE),
mWearableType(type),
mPrimNameMap(&primNameMap)
{
}
LLSD LLExportable::asLLSD()
{
if(mType == EXPORTABLE_OBJECT)
{
std::list<LLViewerObject*> prims;
prims.push_back(mObject);
LLViewerObject::child_list_t child_list = mObject->getChildren();
for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
{
LLViewerObject* child = *i;
if(child->getPCode() < LL_PCODE_APP)
{
prims.push_back(child);
}
}
LLSD llsd;
std::list<LLViewerObject*>::iterator prim_iter = prims.begin();
std::list<LLViewerObject*>::iterator prims_end = prims.end();
for( ; prim_iter != prims_end; ++prim_iter)
{
LLViewerObject* object = (*prim_iter);
LLSD prim_llsd;
prim_llsd["type"] = "prim";
if (!object->isRoot())
{
if(!object->getSubParent()->isAvatar())
{
// Parent id
prim_llsd["parent"] = llformat("%d", object->getSubParent()->getLocalID());
}
}
if(object->getSubParent())
{
if(object->getSubParent()->isAvatar())
{
// attachment-specific
U8 state = object->getState();
S32 attachpt = ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4)));
prim_llsd["attach"] = attachpt;
}
}
// Transforms
prim_llsd["position"] = object->getPosition().getValue();
prim_llsd["scale"] = object->getScale().getValue();
prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
// Flags
prim_llsd["shadows"] = object->flagCastShadows();
prim_llsd["phantom"] = object->flagPhantom();
prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS);
// Volume params
LLVolumeParams params = object->getVolume()->getParams();
prim_llsd["volume"] = params.asLLSD();
// Extra params
if (object->isFlexible())
{
// Flexible
LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
prim_llsd["flexible"] = flex->asLLSD();
}
if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
{
// Light
LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
prim_llsd["light"] = light->asLLSD();
}
if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
{
// Sculpt
LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
prim_llsd["sculpt"] = sculpt->asLLSD();
}
// Textures
LLSD te_llsd;
U8 te_count = object->getNumTEs();
for (U8 i = 0; i < te_count; i++)
{
te_llsd.append(object->getTE(i)->asLLSD());
}
prim_llsd["textures"] = te_llsd;
std::map<U32,std::string>::iterator pos = (*mPrimNameMap).find(object->getLocalID());
if(pos != (*mPrimNameMap).end())
prim_llsd["name"] = (*mPrimNameMap)[object->getLocalID()];
llsd[llformat("%d", object->getLocalID())] = prim_llsd;
}
return llsd;
}
else if(mType == EXPORTABLE_WEARABLE)
{
LLSD llsd; // pointless map with single key/value
LLSD item_sd; // map for wearable
item_sd["type"] = "wearable";
S32 type_s32 = (S32)mWearableType;
std::string wearable_name = LLWearable::typeToTypeName( mWearableType );
item_sd["name"] = mAvatar->getFullname() + " " + wearable_name;
item_sd["wearabletype"] = type_s32;
LLSD param_map;
for( LLVisualParam* param = mAvatar->getFirstVisualParam(); param; param = mAvatar->getNextVisualParam() )
{
LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
if( (viewer_param->getWearableType() == type_s32) &&
(viewer_param->isTweakable()) )
{
param_map[llformat("%d", viewer_param->getID())] = viewer_param->getWeight();
}
}
item_sd["params"] = param_map;
LLSD textures_map;
for( S32 te = 0; te < LLVOAvatarDefines::TEX_NUM_INDICES; te++ )
{
if( LLVOAvatar::getTEWearableType( (LLVOAvatarDefines::ETextureIndex)te ) == mWearableType )
{
LLViewerTexture* te_image = mAvatar->getTEImage( te );
if( te_image )
{
textures_map[llformat("%d", te)] = te_image->getID();
}
}
}
item_sd["textures"] = textures_map;
// Generate a unique ID for it...
LLUUID myid;
myid.generate();
llsd[myid.asString()] = item_sd;
return llsd;
}
return LLSD();
}
LLFloaterExport::LLFloaterExport()
: LLFloater()
{
mSelection = LLSelectMgr::getInstance()->getSelection();
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_export.xml");
LLFloaterExport::instances.push_back(this);
}
LLFloaterExport::~LLFloaterExport()
{
std::vector<LLFloaterExport*>::iterator pos = std::find(LLFloaterExport::instances.begin(), LLFloaterExport::instances.end(), this);
if(pos != LLFloaterExport::instances.end())
{
LLFloaterExport::instances.erase(pos);
}
}
BOOL LLFloaterExport::postBuild(void)
{
if(!mSelection) return TRUE;
if(mSelection->getRootObjectCount() < 1) return TRUE;
// New stuff: Populate prim name map
for (LLObjectSelection::valid_iterator iter = mSelection->valid_begin();
iter != mSelection->valid_end(); iter++)
{
LLSelectNode* nodep = *iter;
LLViewerObject* objectp = nodep->getObject();
U32 localid = objectp->getLocalID();
std::string name = nodep->mName;
mPrimNameMap[localid] = name;
}
// Older stuff
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
std::map<LLViewerObject*, bool> avatars;
for (LLObjectSelection::valid_root_iterator iter = mSelection->valid_root_begin();
iter != mSelection->valid_root_end(); iter++)
{
LLSelectNode* nodep = *iter;
LLViewerObject* objectp = nodep->getObject();
std::string objectp_id = llformat("%d", objectp->getLocalID());
if(list->getItemIndex(objectp->getID()) == -1)
{
bool is_attachment = false;
bool is_root = true;
LLViewerObject* parentp = objectp->getSubParent();
if(parentp)
{
if(!parentp->isAvatar())
{
// parent is a prim I guess
is_root = false;
}
else
{
// parent is an avatar
is_attachment = true;
if(!avatars[parentp]) avatars[parentp] = true;
}
}
bool is_prim = true;
if(objectp->getPCode() >= LL_PCODE_APP)
{
is_prim = false;
}
bool is_avatar = objectp->isAvatar();
if(is_root && is_prim)
{
LLSD element;
element["id"] = objectp->getID();
LLSD& check_column = element["columns"][LIST_CHECKED];
check_column["column"] = "checked";
check_column["type"] = "checkbox";
check_column["value"] = true;
LLSD& type_column = element["columns"][LIST_TYPE];
type_column["column"] = "type";
type_column["type"] = "icon";
type_column["value"] = "inv_item_object.tga";
LLSD& name_column = element["columns"][LIST_NAME];
name_column["column"] = "name";
if(is_attachment)
name_column["value"] = nodep->mName + " (worn on " + utf8str_tolower(objectp->getAttachmentPointName()) + ")";
else
name_column["value"] = nodep->mName;
LLSD& avatarid_column = element["columns"][LIST_AVATARID];
avatarid_column["column"] = "avatarid";
if(is_attachment)
avatarid_column["value"] = parentp->getID();
else
avatarid_column["value"] = LLUUID::null;
LLExportable* exportable = new LLExportable(objectp, nodep->mName, mPrimNameMap);
mExportables[objectp->getID()] = exportable->asLLSD();
list->addElement(element, ADD_BOTTOM);
addToPrimList(objectp);
}
else if(is_avatar)
{
if(!avatars[objectp])
{
avatars[objectp] = true;
}
}
}
}
std::map<LLViewerObject*, bool>::iterator avatar_iter = avatars.begin();
std::map<LLViewerObject*, bool>::iterator avatars_end = avatars.end();
for( ; avatar_iter != avatars_end; avatar_iter++)
{
LLViewerObject* avatar = (*avatar_iter).first;
addAvatarStuff((LLVOAvatar*)avatar);
}
updateNamesProgress();
childSetAction("select_all_btn", onClickSelectAll, this);
childSetAction("select_objects_btn", onClickSelectObjects, this);
childSetAction("select_wearables_btn", onClickSelectWearables, this);
childSetAction("save_as_btn", onClickSaveAs, this);
childSetAction("make_copy_btn", onClickMakeCopy, this);
return TRUE;
}
void LLFloaterExport::addAvatarStuff(LLVOAvatar* avatarp)
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
for( S32 type = WT_SHAPE; type < WT_COUNT; type++ )
{
// guess whether this wearable actually exists
// by checking whether it has any textures that aren't default
bool exists = false;
if(type == WT_SHAPE)
{
exists = true;
}
else if (type == WT_ALPHA || type == WT_TATTOO) //alpha layers and tattos are unsupported for now
{
continue;
}
else
{
for( S32 te = 0; te < LLVOAvatarDefines::TEX_NUM_INDICES; te++ )
{
if( (S32)LLVOAvatar::getTEWearableType( (LLVOAvatarDefines::ETextureIndex)te ) == type )
{
LLViewerTexture* te_image = avatarp->getTEImage( te );
if( te_image->getID() != IMG_DEFAULT_AVATAR)
{
exists = true;
break;
}
}
}
}
if(exists)
{
std::string wearable_name = LLWearable::typeToTypeName( (EWearableType)type );
std::string name = avatarp->getFullname() + " " + wearable_name;
LLUUID myid;
myid.generate();
LLSD element;
element["id"] = myid;
LLSD& check_column = element["columns"][LIST_CHECKED];
check_column["column"] = "checked";
check_column["type"] = "checkbox";
check_column["value"] = false;
LLSD& type_column = element["columns"][LIST_TYPE];
type_column["column"] = "type";
type_column["type"] = "icon";
type_column["value"] = "inv_item_" + wearable_name + ".tga";
LLSD& name_column = element["columns"][LIST_NAME];
name_column["column"] = "name";
name_column["value"] = name;
LLSD& avatarid_column = element["columns"][LIST_AVATARID];
avatarid_column["column"] = "avatarid";
avatarid_column["value"] = avatarp->getID();
LLExportable* exportable = new LLExportable(avatarp, (EWearableType)type, mPrimNameMap);
mExportables[myid] = exportable->asLLSD();
list->addElement(element, ADD_BOTTOM);
}
}
// Add attachments
LLViewerObject::child_list_t child_list = avatarp->getChildren();
for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
{
LLViewerObject* childp = *i;
if(list->getItemIndex(childp->getID()) == -1)
{
LLSD element;
element["id"] = childp->getID();
LLSD& check_column = element["columns"][LIST_CHECKED];
check_column["column"] = "checked";
check_column["type"] = "checkbox";
check_column["value"] = false;
LLSD& type_column = element["columns"][LIST_TYPE];
type_column["column"] = "type";
type_column["type"] = "icon";
type_column["value"] = "inv_item_object.tga";
LLSD& name_column = element["columns"][LIST_NAME];
name_column["column"] = "name";
name_column["value"] = "Object (worn on " + utf8str_tolower(childp->getAttachmentPointName()) + ")";
LLSD& avatarid_column = element["columns"][LIST_AVATARID];
avatarid_column["column"] = "avatarid";
avatarid_column["value"] = avatarp->getID();
LLExportable* exportable = new LLExportable(childp, "Object", mPrimNameMap);
mExportables[childp->getID()] = exportable->asLLSD();
list->addElement(element, ADD_BOTTOM);
addToPrimList(childp);
//LLSelectMgr::getInstance()->selectObjectAndFamily(childp, false);
//LLSelectMgr::getInstance()->deselectObjectAndFamily(childp, true, true);
LLViewerObject::child_list_t select_list = childp->getChildren();
LLViewerObject::child_list_t::iterator select_iter;
int block_counter;
gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID());
block_counter = 0;
for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter)
{
block_counter++;
if(block_counter >= 254)
{
// start a new message
gMessageSystem->sendReliable(childp->getRegion()->getHost());
gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
}
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID());
}
gMessageSystem->sendReliable(childp->getRegion()->getHost());
gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID());
block_counter = 0;
for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter)
{
block_counter++;
if(block_counter >= 254)
{
// start a new message
gMessageSystem->sendReliable(childp->getRegion()->getHost());
gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
}
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID());
}
gMessageSystem->sendReliable(childp->getRegion()->getHost());
}
}
}
//static
void LLFloaterExport::onClickSelectAll(void* user_data)
{
LLFloaterExport* floater = (LLFloaterExport*)user_data;
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
std::vector<LLScrollListItem*> items = list->getAllData();
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
std::vector<LLScrollListItem*>::iterator items_end = items.end();
bool new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
for( ; item_iter != items_end; ++item_iter)
{
LLScrollListItem* item = (*item_iter);
item->getColumn(LIST_CHECKED)->setValue(new_value);
}
}
//static
void LLFloaterExport::onClickSelectObjects(void* user_data)
{
LLFloaterExport* floater = (LLFloaterExport*)user_data;
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
std::vector<LLScrollListItem*> items = list->getAllData();
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
std::vector<LLScrollListItem*>::iterator items_end = items.end();
bool new_value = false;
for( ; item_iter != items_end; ++item_iter)
{
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga")
{
new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
break;
}
}
for(item_iter = items.begin(); item_iter != items_end; ++item_iter)
{
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga")
{
LLScrollListItem* item = (*item_iter);
item->getColumn(LIST_CHECKED)->setValue(new_value);
}
}
}
//static
void LLFloaterExport::onClickSelectWearables(void* user_data)
{
LLFloaterExport* floater = (LLFloaterExport*)user_data;
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
std::vector<LLScrollListItem*> items = list->getAllData();
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
std::vector<LLScrollListItem*>::iterator items_end = items.end();
bool new_value = false;
for( ; item_iter != items_end; ++item_iter)
{
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga")
{
new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
break;
}
}
for(item_iter = items.begin(); item_iter != items_end; ++item_iter)
{
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga")
{
LLScrollListItem* item = (*item_iter);
item->getColumn(LIST_CHECKED)->setValue(new_value);
}
}
}
LLSD LLFloaterExport::getLLSD()
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
std::vector<LLScrollListItem*> items = list->getAllData();
LLSD sd;
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())
{
LLSD item_sd = mExportables[item->getUUID()];
LLSD::map_iterator map_iter = item_sd.beginMap();
LLSD::map_iterator map_end = item_sd.endMap();
for( ; map_iter != map_end; ++map_iter)
{
std::string key((*map_iter).first);
LLSD data = (*map_iter).second;
// copy it...
sd[key] = data;
}
}
}
return sd;
}
//static
void LLFloaterExport::onClickSaveAs(void* user_data)
{
LLFloaterExport* floater = (LLFloaterExport*)user_data;
LLSD sd = floater->getLLSD();
if(sd.size())
{
std::string default_filename = "untitled";
// 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;
LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(textures.front());
img->setBoostLevel(LLViewerTexture::BOOST_MAX_LEVEL);
CacheReadResponder* responder = new CacheReadResponder(textures.front(), std::string(path + textures.front().asString() + ".j2c"));
LLAppViewer::getTextureCache()->readFromCache(textures.front(),LLWorkerThread::PRIORITY_HIGH,0,999999,responder);
textures.pop_front();
}
}
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);
}
}
else
{
std::string msg = "No exportable items selected";
LLChat chat(msg);
LLFloaterChat::addChat(chat);
return;
}
floater->close();
}
//static
void LLFloaterExport::onClickMakeCopy(void* user_data)
{
LLFloaterExport* floater = (LLFloaterExport*)user_data;
LLSD sd = floater->getLLSD();
if(sd.size())
{
LLXmlImport::import(new LLXmlImportOptions(sd));
}
else
{
std::string msg = "No copyable items selected";
LLChat chat(msg);
LLFloaterChat::addChat(chat);
return;
}
// I guess close the floater because only one import is allowed at once anyway
floater->close();
}
void LLFloaterExport::addToPrimList(LLViewerObject* object)
{
mPrimList.push_back(object->getLocalID());
LLViewerObject::child_list_t child_list = object->getChildren();
for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
{
LLViewerObject* child = *i;
if(child->getPCode() < LL_PCODE_APP)
{
mPrimList.push_back(child->getLocalID());
}
}
}
void LLFloaterExport::updateNamesProgress()
{
childSetText("names_progress_text", llformat("Names retrieved: %d of %d", mPrimNameMap.size(), mPrimList.size()));
}
void LLFloaterExport::receivePrimName(LLViewerObject* object, std::string name)
{
LLUUID fullid = object->getID();
U32 localid = object->getLocalID();
if(std::find(mPrimList.begin(), mPrimList.end(), localid) != mPrimList.end())
{
mPrimNameMap[localid] = name;
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
S32 item_index = list->getItemIndex(fullid);
if(item_index != -1)
{
std::vector<LLScrollListItem*> items = list->getAllData();
std::vector<LLScrollListItem*>::iterator iter = items.begin();
std::vector<LLScrollListItem*>::iterator end = items.end();
for( ; iter != end; ++iter)
{
if((*iter)->getUUID() == fullid)
{
(*iter)->getColumn(LIST_NAME)->setValue(name + " (worn on " + utf8str_tolower(object->getAttachmentPointName()) + ")");
break;
}
}
}
updateNamesProgress();
}
}
// static
void LLFloaterExport::receiveObjectProperties(LLUUID fullid, std::string name, std::string desc)
{
LLViewerObject* object = gObjectList.findObject(fullid);
std::vector<LLFloaterExport*>::iterator iter = LLFloaterExport::instances.begin();
std::vector<LLFloaterExport*>::iterator end = LLFloaterExport::instances.end();
for( ; iter != end; ++iter)
{
(*iter)->receivePrimName(object, name);
}
}
// </edit>