Wearable import/export, from Imprudence
This commit is contained in:
@@ -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", ¶m_id, ¶m_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 )
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user