Wearable import/export, from Imprudence

This commit is contained in:
Siana Gearz
2011-04-19 13:46:09 +02:00
parent 955ca21298
commit 8f09dedb1e
5 changed files with 182 additions and 11 deletions

View File

@@ -1700,17 +1700,11 @@ BOOL LLFloaterCustomize::postBuild()
childSetAction("Make Outfit", LLFloaterCustomize::onBtnMakeOutfit, (void*)this);
childSetAction("Ok", LLFloaterCustomize::onBtnOk, (void*)this);
childSetAction("Cancel", LLFloater::onClickClose, (void*)this);
// OGPX : if using agent domain, disable saving appearance until inventory and assets is working
// since it doesn't work in OGP right now, disable it, since enabling it hits an error case.
// OGPX TODO: test with it enabled with Agent Domain that manages Inventory and Assets
// This was originally added as part of OGP9 svn branch because the viewer deeply deeply
// assumes that there *will* be an inventory there. If you never get an inventory,
// Make Outfit breaks badly.
//if (!gSavedSettings.getString("CmdLineRegionURI").empty())
//{
// childSetEnabled("Make Outfit", FALSE);
//}
// reX
childSetAction("Import", LLFloaterCustomize::onBtnImport, (void*)this);
childSetAction("Export", LLFloaterCustomize::onBtnExport, (void*)this);
// Wearable panels
initWearablePanels();
@@ -1779,6 +1773,128 @@ void LLFloaterCustomize::setCurrentWearableType( EWearableType type )
}
}
// reX: new function
void LLFloaterCustomize::onBtnImport( void* userdata )
{
LLFilePicker& file_picker = LLFilePicker::instance();
if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_XML ) )
{
// User canceled import.
return;
}
const std::string filename = file_picker.getFirstFile();
FILE* fp = LLFile::fopen(filename, "rb");
//char text_buffer[2048]; /* Flawfinder: ignore */
S32 c;
S32 typ;
S32 count;
S32 param_id=0;
F32 param_weight=0;
S32 fields_read;
for( S32 i=0; i < WT_COUNT; i++ )
{
fields_read = fscanf( fp, "type %d\n", &typ);
if( fields_read != 1 )
{
llwarns << "Bad asset type: early end of file" << llendl;
return;
}
fields_read = fscanf( fp, "parameters %d\n", &count);
if( fields_read != 1 )
{
llwarns << "Bad parameters : early end of file" << llendl;
return;
}
for(c=0;c<count;c++)
{
fields_read = fscanf( fp, "%d %f\n", &param_id, &param_weight );
if( fields_read != 2 )
{
llwarns << "Bad parameters list: early end of file" << llendl;
return;
}
gAgent.getAvatarObject()->setVisualParamWeight( param_id, param_weight, TRUE);
gAgent.getAvatarObject()->updateVisualParams();
}
}
fclose(fp);
return;
}
// reX: new function
void LLFloaterCustomize::onBtnExport( void* userdata )
{
LLFilePicker& file_picker = LLFilePicker::instance();
if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_XML ) )
{
// User canceled export.
return;
}
LLViewerInventoryItem* item;
BOOL is_modifiable;
const std::string filename = file_picker.getFirstFile();
FILE* fp = LLFile::fopen(filename, "wb");
for( S32 i=0; i < WT_COUNT; i++ )
{
is_modifiable = FALSE;
LLWearable* old_wearable = gAgent.getWearable((EWearableType)i);
if( old_wearable )
{
item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem((EWearableType)i);
if(item)
{
const LLPermissions& perm = item->getPermissions();
is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID());
}
}
if (is_modifiable)
{
old_wearable->FileExportParams(fp);
}
if (!is_modifiable)
{
fprintf( fp, "type %d\n",i);
fprintf( fp, "parameters 0\n");
}
}
for( S32 i=0; i < WT_COUNT; i++ )
{
is_modifiable = FALSE;
LLWearable* old_wearable = gAgent.getWearable((EWearableType)i);
if( old_wearable )
{
item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem((EWearableType)i);
if(item)
{
const LLPermissions& perm = item->getPermissions();
is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID());
}
}
if (is_modifiable)
{
old_wearable->FileExportTextures(fp);
}
if (!is_modifiable)
{
fprintf( fp, "type %d\n",i);
fprintf( fp, "textures 0\n");
}
}
fclose(fp);
}
// static
void LLFloaterCustomize::onBtnOk( void* userdata )
{

View File

@@ -109,6 +109,8 @@ public:
static void onBtnOk( void* userdata );
static void onBtnMakeOutfit( void* userdata );
static void onMakeOutfitCommit( LLMakeOutfitDialog* dialog, void* userdata );
static void onBtnImport( void* userdata );
static void onBtnExport( void* userdata );
static void onTabChanged( void* userdata, bool from_click );
static void onTabPrecommit( void* userdata, bool from_click );

View File

@@ -194,6 +194,50 @@ std::string terse_F32_to_string( F32 f )
return r;
}
// reX: new function
BOOL LLWearable::FileExportParams( FILE* file )
{
// wearable type
S32 type = (S32)mType;
fprintf( file, "type %d\n", type );
// parameters
S32 num_parameters = mVisualParamMap.size();
fprintf( file, "parameters %d\n", num_parameters );
for (param_map_t::iterator iter = mVisualParamMap.begin();
iter != mVisualParamMap.end(); ++iter)
{
S32 param_id = iter->first;
F32 param_weight = iter->second;
fprintf( file, "%d %s\n", param_id, terse_F32_to_string(param_weight).c_str() );
}
return TRUE;
}
// reX: new function
BOOL LLWearable::FileExportTextures( FILE* file )
{
// wearable type
S32 type = (S32)mType;
fprintf( file, "type %d\n", type );
// texture entries
S32 num_textures = mTEMap.size();
fprintf( file, "textures %d\n", num_textures );
for (te_map_t::iterator iter = mTEMap.begin();
iter != mTEMap.end(); ++iter)
{
S32 te = iter->first;
LLUUID& image_id = iter->second;
fprintf( file, "%d %s\n", te, image_id.asString().c_str() );
}
return TRUE;
}
BOOL LLWearable::exportFile( LLFILE* file )
{
// header and version

View File

@@ -81,6 +81,9 @@ public:
BOOL exportFile(LLFILE* file);
BOOL importFile(LLFILE* file);
BOOL FileExportParams(FILE* file);
BOOL FileExportTextures(FILE* file);
EWearableType getType() const { return mType; }
void setType( EWearableType type ) { mType = type; }

View File

@@ -1319,6 +1319,12 @@ scratch and wear it.
left="8" mouse_opaque="true" name="HeightTextI" v_pad="0" width="140">
(imperial)
</text>
<button name="Import" label="Import"
bottom="-486" left="10" height="20" width="70"
follows="left|bottom" font="SansSerif" halign="center" />
<button name="Export" label="Export"
bottom="-506" left="10" height="20" width="70"
follows="left|bottom" font="SansSerif" halign="center" />
<button bottom="-536" follows="right|bottom" font="SansSerif" halign="center"
height="20" label="Cancel" label_selected="Cancel" mouse_opaque="true"
name="Cancel" right="-10" scale_image="true" width="100" />
@@ -1327,6 +1333,6 @@ scratch and wear it.
name="Ok" right="-116" scale_image="true" width="100" />
<button bottom="-536" follows="left|bottom" font="SansSerif" halign="center"
height="20" label="Make Outfit..." label_selected="Make Outfit..."
mouse_opaque="true" name="Make Outfit" left="100" scale_image="true"
mouse_opaque="true" name="Make Outfit" left="10" scale_image="true"
width="100" />
</floater>