diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index c4704bf06..379465eb2 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -33,6 +33,7 @@ #include "llvisualparam.h" #include "llavatarappearancedefines.h" #include "llwearable.h" +#include "lldate.h" using namespace LLAvatarAppearanceDefines; @@ -68,47 +69,42 @@ LLAssetType::EType LLWearable::getAssetType() const return LLWearableType::getAssetType(mType); } -// reX: new function -BOOL LLWearable::FileExportParams( FILE* file ) const +extern void dump_visual_param(LLAPRFile& file, LLVisualParam const* viewer_param, F32 value); + +// Replace '--' with '- -', see http://en.wikipedia.org/wiki/XML#Comments +std::string XMLCommentEscape(std::string const& comment) { - // wearable type - S32 type = (S32)mType; - fprintf( file, "type %d\n", type ); - - // parameters - S32 num_parameters = mVisualParamIndexMap.size(); - fprintf( file, "parameters %d\n", num_parameters ); - - for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); - iter != mVisualParamIndexMap.end(); ++iter) - { - S32 param_id = iter->first; - F32 param_weight = iter->second->getWeight(); - fprintf( file, "%d %s\n", param_id, terse_F32_to_string(param_weight).c_str() ); - } - - return TRUE; + std::string result = comment; + std::string::size_type off = std::string::npos; + while ((off = result.rfind("--", off)) != std::string::npos) + { + result.replace(off, 2, "- -"); + } + return result; } -// reX: new function -BOOL LLWearable::FileExportTextures( FILE* file ) const +void LLWearable::archetypeExport(LLAPRFile& file) const { - // wearable type - S32 type = (S32)mType; - fprintf( file, "type %d\n", type ); + apr_file_t* fp = file.getFileHandle(); - // texture entries - S32 num_textures = mTEMap.size(); - fprintf( file, "textures %d\n", num_textures ); - - for (te_map_t::const_iterator iter = mTEMap.begin(); - iter != mTEMap.end(); ++iter) + apr_file_printf(fp, "\n\t\t\n", getTypeName().c_str()); + apr_file_printf(fp, "\t\t\n", XMLCommentEscape(mName).c_str()); + apr_file_printf(fp, "\t\t\n", XMLCommentEscape(mDescription).c_str()); + apr_file_printf(fp, "\t\t\n", LLDate::now().asString().c_str()); + + for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter) + { + LLVisualParam const* param = iter->second; + dump_visual_param(file, param, param->getWeight()); + } + for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter) { S32 te = iter->first; - fprintf( file, "%d %s\n", te, iter->second->getID().asString().c_str() ); - } + LLUUID const& image_id = iter->second->getID(); + apr_file_printf(fp, "\t\t\n", te, image_id.asString().c_str()); + } - return TRUE; + apr_file_printf(fp, "\n"); } BOOL LLWearable::exportFile(LLFILE* fp) const diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index e3f54b60e..f381835be 100644 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -35,6 +35,7 @@ #include "llwearabletype.h" #include "lllocaltextureobject.h" +class LLAPRFile; class LLMD5; class LLVisualParam; class LLTexGlobalColorInfo; @@ -77,9 +78,8 @@ public: virtual void writeToAvatar(LLAvatarAppearance* avatarp); - BOOL FileExportParams(FILE* file) const; - BOOL FileExportTextures(FILE* file) const; - + void archetypeExport(LLAPRFile& file) const; + enum EImportResult { FAILURE = 0, diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 25e984503..50c8bc5cc 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4439,7 +4439,7 @@ void LLAgent::requestLeaveGodMode() sendReliableMessage(); } -extern void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value); +extern void dump_visual_param(LLAPRFile& file, LLVisualParam const* viewer_param, F32 value); extern std::string get_sequential_numbered_file_name(const std::string& prefix, const std::string& suffix); @@ -4465,7 +4465,7 @@ void LLAgent::dumpSentAppearance(const std::string& dump_prefix) if (appearance_version_param) { F32 value = appearance_version_param->getWeight(); - dump_visual_param(file, appearance_version_param, value); + dump_visual_param(outfile, appearance_version_param, value); } for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index c757697b3..0b8b80963 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -81,6 +81,7 @@ #include "llappearancemgr.h" #include "statemachine/aifilepicker.h" +#include "llxmltree.h" using namespace LLAvatarAppearanceDefines; @@ -297,7 +298,7 @@ void LLFloaterCustomize::onBtnImport() { AIFilePicker* filepicker = AIFilePicker::create(); filepicker->open(FFLOAD_XML); - filepicker->run(boost::bind(&LLFloaterCustomize::onBtnImport_continued, filepicker)); + filepicker->run(boost::bind(&LLFloaterCustomize::onBtnImport_continued, this, filepicker)); } void LLFloaterCustomize::onBtnImport_continued(AIFilePicker* filepicker) @@ -308,59 +309,123 @@ void LLFloaterCustomize::onBtnImport_continued(AIFilePicker* filepicker) return; } - const std::string filename = filepicker->getFilename(); + // Find the editted wearable. + LLPanelEditWearable* panel_edit_wearable = getCurrentWearablePanel(); + LLViewerWearable* edit_wearable = panel_edit_wearable->getWearable(); - FILE* fp = LLFile::fopen(filename, "rb"); + std::string const filename = filepicker->getFilename(); - //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 < LLWearableType::WT_COUNT; i++ ) + LLXmlTree xml; + BOOL success = xml.parseFile(filename, FALSE); + if (!success) { - fields_read = fscanf( fp, "type %d\n", &typ); - if( fields_read != 1 ) - { - llwarns << "Bad asset type: early end of file" << llendl; - return; - } + llwarns << "Could not read or parse wearable import file \"" << filename << "\"." << llendl; + return; + } + LLXmlTreeNode* root = xml.getRoot(); + if (!root) + { + llwarns << "No root node found in wearable import file: " << filename << 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;csetVisualParamWeight(param_id, param_weight, TRUE); - } + //------------------------------------------------------------------------- + // (root) + //------------------------------------------------------------------------- + if (!root->hasName("linden_genepool")) + { + llwarns << "Invalid wearable import file (missing linden_genepool header): " << filename << llendl; + return; + } + static LLStdStringHandle const version_string = LLXmlTree::addAttributeString("version"); + std::string version; + if (!root->getFastAttributeString(version_string, version) || (version != "1.0")) + { + llwarns << "Invalid linden_genepool version: " << version << " in file: " << filename << llendl; + return; } - fclose(fp); - return; + //------------------------------------------------------------------------- + // + //------------------------------------------------------------------------- + LLXmlTreeNode* archetype_node = root->getChildByName("archetype"); + if (!archetype_node) + { + llwarns << "No archetype in wearable import file: " << filename << llendl; + return; + } + + // Parse the XML content. + static LLStdStringHandle const id_string = LLXmlTree::addAttributeString("id"); + static LLStdStringHandle const value_string = LLXmlTree::addAttributeString("value"); + for(LLXmlTreeNode* child = archetype_node->getFirstChild(); child; child = archetype_node->getNextChild()) + { + if (!child->hasName("param")) + { + continue; + } + std::string id_s; + U32 id; + std::string value_s; + F32 value; + if (!child->getFastAttributeString(id_string, id_s) || !LLStringUtil::convertToU32(id_s, id) || + !child->getFastAttributeString(value_string, value_s) || !LLStringUtil::convertToF32(value_s, value)) + { + llwarns << "Possible syntax error or corruption for node in " << filename << llendl; + continue; + } + LLVisualParam* visual_param = edit_wearable->getVisualParam(id); + if (visual_param) + { + visual_param->setWeight(value, FALSE); + } + } + edit_wearable->writeToAvatar(gAgentAvatarp); + gAgentAvatarp->updateVisualParams(); + panel_edit_wearable->updateScrollingPanelUI(); } // reX: new function void LLFloaterCustomize::onBtnExport() { + // Find the editted wearable. + LLPanelEditWearable* panel_edit_wearable = getCurrentWearablePanel(); + LLViewerWearable* edit_wearable = panel_edit_wearable->getWearable(); + U32 edit_index = panel_edit_wearable->getIndex(); + std::string const& name = edit_wearable->getName(); + + // Determine if the currently selected wearable is modifiable. + LLWearableType::EType edit_type = getCurrentWearableType(); + bool is_modifiable = false; + LLViewerWearable* old_wearable = gAgentWearables.getViewerWearable(edit_type, edit_index); + if (old_wearable) + { + LLViewerInventoryItem* item = gInventory.getItem(old_wearable->getItemID()); + if (item) + { + LLPermissions const& perm = item->getPermissions(); + // Modifiable means the user can see the sliders and type them over into a file anyway. + is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID()); + } + } + + if (!is_modifiable) + { + // We should never get here, because in that case the Export button is disabled. + llwarns << "Cannot export current wearable \"" << name << "\" of type " << (int)edit_type << "because user lacks modify permissions." << llendl; + return; + } + + std::string file_name = edit_wearable->getName() + "_" + edit_wearable->getTypeName() + "?000.xml"; + std::string default_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); + AIFilePicker* filepicker = AIFilePicker::create(); - filepicker->open("", FFSAVE_XML); - filepicker->run(boost::bind(&LLFloaterCustomize::onBtnExport_continued, filepicker)); + filepicker->open(file_name, FFSAVE_XML, default_path, "archetype"); + filepicker->run(boost::bind(&LLFloaterCustomize::onBtnExport_continued, edit_wearable, filepicker)); } -void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker) +//static +void LLFloaterCustomize::onBtnExport_continued(LLViewerWearable* edit_wearable, AIFilePicker* filepicker) { if (!filepicker->hasFilename()) { @@ -368,62 +433,17 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker) return; } - LLViewerInventoryItem* item; - BOOL is_modifiable; - - const std::string filename = filepicker->getFilename(); - - FILE* fp = LLFile::fopen(filename, "wb"); - - for( S32 i=0; i < LLWearableType::WT_COUNT; i++ ) + LLAPRFile outfile; + outfile.open(filepicker->getFilename(), LL_APR_WB); + if (!outfile.getFileHandle()) { - is_modifiable = FALSE; - LLViewerWearable* old_wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE - if( old_wearable ) - { - item = gInventory.getItem(old_wearable->getItemID()); - 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"); - } - } + llwarns << "Could not open \"" << filepicker->getFilename() << "\" for writing." << llendl; + return; + } - for( S32 i=0; i < LLWearableType::WT_COUNT; i++ ) - { - is_modifiable = FALSE; - LLViewerWearable* old_wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)i, 0); // TODO: MULTI-WEARABLE - if( old_wearable ) - { - item = gInventory.getItem(old_wearable->getItemID()); - 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); + LLVOAvatar::dumpArchetypeXML_header(outfile); + edit_wearable->archetypeExport(outfile); + LLVOAvatar::dumpArchetypeXML_footer(outfile); } void LLFloaterCustomize::onBtnOk() diff --git a/indra/newview/llfloatercustomize.h b/indra/newview/llfloatercustomize.h index 34eee55fe..115ad61ac 100644 --- a/indra/newview/llfloatercustomize.h +++ b/indra/newview/llfloatercustomize.h @@ -125,9 +125,9 @@ private: void onBtnOk(); void onBtnMakeOutfit(); void onBtnImport(); - static void onBtnImport_continued(AIFilePicker* filepicker); + void onBtnImport_continued(AIFilePicker* filepicker); void onBtnExport(); - static void onBtnExport_continued(AIFilePicker* filepicker); + static void onBtnExport_continued(LLViewerWearable* edit_wearable, AIFilePicker* filepicker); void onTabChanged( const LLSD& param ); bool onTabPrecommit( LLUICtrl* ctrl, const LLSD& param ); bool onSaveDialog(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 78ef25eed..7719b2dfa 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -953,22 +953,8 @@ void LLPanelEditWearable::setWearableIndex(S32 index) if(mActiveModal) mActiveModal->close(); - U32 perm_mask = wearable ? PERM_NONE : PERM_ALL; - BOOL is_complete = wearable ? FALSE : TRUE; - if(wearable) - { - LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(wearable->getItemID()); - if(item) - { - perm_mask = item->getPermissions().getMaskOwner(); - is_complete = item->isComplete(); - if(!is_complete) - { - item->fetchFromServer(); - } - } - } - setUIPermissions(perm_mask, is_complete); + bool editable = updatePermissions(); + if (mType == LLWearableType::WT_ALPHA) { initPreviousAlphaTextures(); @@ -980,7 +966,7 @@ void LLPanelEditWearable::setWearableIndex(S32 index) if(subpart_entry) { value_map_t sorted_params; - getSortedParams(sorted_params, subpart_entry->mEditGroup, ((perm_mask & PERM_MODIFY) && is_complete) ? TRUE : FALSE); + getSortedParams(sorted_params, subpart_entry->mEditGroup, editable); buildParamList(mCustomizeFloater->getScrollingPanelList(), sorted_params); } @@ -1144,6 +1130,10 @@ LLViewerWearable* LLPanelEditWearable::getWearable() const return mCurrentWearable;//gAgentWearables.getWearable(mType, mCurrentIndex); // TODO: MULTI-WEARABLE } +U32 LLPanelEditWearable::getIndex() const +{ + return mCurrentIndex; +} void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl) { @@ -1386,39 +1376,11 @@ void LLPanelEditWearable::changeCamera(U8 subpart) } // Update the thumbnails we display - LLViewerWearable* wearable = getWearable(); - LLViewerInventoryItem* item = wearable ? gInventory.getItem(wearable->getItemID()) : NULL; - U32 perm_mask = 0x0; - BOOL is_complete = FALSE; - bool can_export = false; - bool can_import = false; - if(item) - { - perm_mask = item->getPermissions().getMaskOwner(); - is_complete = item->isComplete(); - - if (subpart_e < SUBPART_EYES) // body parts only - { - can_import = true; - - if (is_complete && - gAgent.getID() == item->getPermissions().getOwner() && - gAgent.getID() == item->getPermissions().getCreator() && - (PERM_ITEM_UNRESTRICTED & - perm_mask) == PERM_ITEM_UNRESTRICTED) - { - can_export = true; - } - } - } - setUIPermissions(perm_mask, is_complete); - + bool editable = updatePermissions(); value_map_t sorted_params; - getSortedParams(sorted_params, subpart_entry->mEditGroup, ((perm_mask & PERM_MODIFY) && is_complete) ? TRUE : FALSE); + getSortedParams(sorted_params, subpart_entry->mEditGroup, editable); buildParamList(mCustomizeFloater->getScrollingPanelList(), sorted_params); updateScrollingPanelUI(); - mCustomizeFloater->childSetEnabled("Export", can_export); - mCustomizeFloater->childSetEnabled("Import", can_import); // Update the camera if(gMorphView) @@ -1434,6 +1396,43 @@ void LLPanelEditWearable::changeCamera(U8 subpart) } } +//Singu note: this function was split off from LLPanelEditWearable::changeCamera +// Return true if the current wearable is editable and update state accordingly. +bool LLPanelEditWearable::updatePermissions() +{ + LLViewerWearable* wearable = getWearable(); + LLViewerInventoryItem* item = wearable ? gInventory.getItem(wearable->getItemID()) : NULL; + U32 perm_mask = wearable ? PERM_NONE : PERM_ALL; + BOOL is_complete = wearable ? FALSE : TRUE; + bool can_export = false; + bool can_import = false; + if (item) + { + perm_mask = item->getPermissions().getMaskOwner(); + is_complete = item->isComplete(); + + //Singu note: allow to import values over any modifiable wearable (why not?). + { + can_import = true; + + // Exporting (of slider values) is allowed when the wearable is full perm, and owned by and created by the user. + // Of course, only modifiable is enough for the user to write down the values and enter them else where... but why make it easy for them to break the ToS. + if (is_complete && + gAgent.getID() == item->getPermissions().getOwner() && + gAgent.getID() == item->getPermissions().getCreator() && + (PERM_ITEM_UNRESTRICTED & + perm_mask) == PERM_ITEM_UNRESTRICTED) + { + can_export = true; + } + } + } + setUIPermissions(perm_mask, is_complete); + mCustomizeFloater->childSetEnabled("Export", can_export); + mCustomizeFloater->childSetEnabled("Import", can_import); + return (perm_mask & PERM_MODIFY) && is_complete; +} + void LLPanelEditWearable::updateScrollingPanelList() { updateScrollingPanelUI(); diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 0509b8e30..f7e9dbade 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -62,10 +62,12 @@ public: // changes camera angle to default for selected subpart void changeCamera(U8 subpart); + bool updatePermissions(); const std::string& getLabel() { return LLWearableType::getTypeLabel( mType ); } LLWearableType::EType getType() const{ return mType; } LLViewerWearable* getWearable() const; + U32 getIndex() const; void onTabChanged(LLUICtrl* ctrl); bool onTabPrecommit(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 389b02629..857d48636 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4376,7 +4376,7 @@ void handle_dump_archetype_xml(void *) avatar = gAgentAvatarp; } - std::string file_name = avatar->getFullname() + (avatar->isSelf() ? "_s" : "_o") + ".xml"; + std::string file_name = avatar->getFullname() + (avatar->isSelf() ? "_s" : "_o") + "?000.xml"; std::string default_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); AIFilePicker* filepicker = AIFilePicker::create(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b406c9eaa..0164c722c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7618,34 +7618,33 @@ bool LLVOAvatar::visualParamWeightsAreDefault() return rtn; } -void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value) +void dump_visual_param(LLAPRFile& file, LLVisualParam const* viewer_param, F32 value) { std::string type_string = "unknown"; - if (dynamic_cast(viewer_param)) + if (dynamic_cast(viewer_param)) type_string = "param_alpha"; - if (dynamic_cast(viewer_param)) + if (dynamic_cast(viewer_param)) type_string = "param_color"; - if (dynamic_cast(viewer_param)) + if (dynamic_cast(viewer_param)) type_string = "param_driver"; - if (dynamic_cast(viewer_param)) + if (dynamic_cast(viewer_param)) type_string = "param_morph"; - if (dynamic_cast(viewer_param)) + if (dynamic_cast(viewer_param)) type_string = "param_skeleton"; S32 wtype = -1; - LLViewerVisualParam *vparam = dynamic_cast(viewer_param); + LLViewerVisualParam const* vparam = dynamic_cast(viewer_param); if (vparam) { wtype = vparam->getWearableType(); } S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight()); - apr_file_printf(file, "\t\t\n", + apr_file_printf(file.getFileHandle(), "\t\t\n", viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(), LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str() // param_location_name(vparam->getParamLocation()).c_str() ); } - void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, const std::vector& params_for_dump, const LLTEContents& tec) @@ -7675,7 +7674,7 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, } LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; F32 value = params_for_dump[i]; - dump_visual_param(file, viewer_param, value); + dump_visual_param(outfile, viewer_param, value); param = getNextVisualParam(); } for (U32 i = 0; i < tec.face_count; i++) @@ -8301,7 +8300,24 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara dumpArchetypeXML_cont(fullpath, group_by_wearables); } -void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_by_wearables ) +//static +void LLVOAvatar::dumpArchetypeXML_header(LLAPRFile& file) +{ + apr_file_t* fp = file.getFileHandle(); + apr_file_printf(fp, "\n"); + apr_file_printf(fp, "\n"); + apr_file_printf(fp, "\n\t\n"); +} + +//static +void LLVOAvatar::dumpArchetypeXML_footer(LLAPRFile& file) +{ + apr_file_t* fp = file.getFileHandle(); + apr_file_printf(fp, "\t\n"); + apr_file_printf(fp, "\n\n"); +} + +void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_by_wearables) { LLAPRFile outfile; outfile.open(fullpath, LL_APR_WB ); @@ -8315,9 +8331,7 @@ void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_b llinfos << "xmlfile write handle obtained : " << fullpath << llendl; } - apr_file_printf( file, "\n" ); - apr_file_printf( file, "\n" ); - apr_file_printf( file, "\n\t\n" ); + LLVOAvatar::dumpArchetypeXML_header(outfile); if (group_by_wearables) { @@ -8332,7 +8346,7 @@ void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_b if( (viewer_param->getWearableType() == type) && (viewer_param->isTweakable() ) ) { - dump_visual_param(file, viewer_param, viewer_param->getWeight()); + dump_visual_param(outfile, viewer_param, viewer_param->getWeight()); } } @@ -8358,7 +8372,7 @@ void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_b for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) { LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - dump_visual_param(file, viewer_param, viewer_param->getWeight()); + dump_visual_param(outfile, viewer_param, viewer_param->getWeight()); } for (U8 te = 0; te < TEX_NUM_INDICES; te++) @@ -8376,8 +8390,8 @@ void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_b } } - apr_file_printf( file, "\t\n" ); - apr_file_printf( file, "\n\n" ); + + LLVOAvatar::dumpArchetypeXML_footer(outfile); bool ultra_verbose = false; if (isSelf() && ultra_verbose) @@ -8388,7 +8402,6 @@ void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_b // File will close when handle goes out of scope } - void LLVOAvatar::setVisibilityRank(U32 rank) { if (mDrawable.isNull() || mDrawable->isDead()) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index a6c2e4c7b..23964a77e 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -66,6 +66,7 @@ extern const LLUUID ANIM_AGENT_PELVIS_FIX; extern const LLUUID ANIM_AGENT_TARGET; extern const LLUUID ANIM_AGENT_WALK_ADJUST; +class LLAPRFile; class LLViewerWearable; class LLVoiceVisualizer; class LLHUDNameTag; @@ -986,6 +987,8 @@ private: // General //-------------------------------------------------------------------- public: + static void dumpArchetypeXML_header(LLAPRFile& file); + static void dumpArchetypeXML_footer(LLAPRFile& file); void dumpArchetypeXML(const std::string& prefix, bool group_by_wearables = false); void dumpArchetypeXML_cont(std::string const& fullpath, bool group_by_wearables); void dumpAppearanceMsgParams( const std::string& dump_prefix, diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 49e9eba37..fc53d4091 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -3195,7 +3195,7 @@ void LLVOAvatarSelf::dumpScratchTextureByteCount() llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl; } -void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value); +void dump_visual_param(LLAPRFile& file, LLVisualParam const* viewer_param, F32 value); void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile) { @@ -3223,7 +3223,7 @@ void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile) it != v_params.end(); ++it) { LLVisualParam *param = *it; - dump_visual_param(file, param, param->getWeight()); + dump_visual_param(outfile, param, param->getWeight()); } } } diff --git a/indra/newview/skins/default/xui/en-us/floater_customize.xml b/indra/newview/skins/default/xui/en-us/floater_customize.xml index e0f6df5b5..b1194eb89 100644 --- a/indra/newview/skins/default/xui/en-us/floater_customize.xml +++ b/indra/newview/skins/default/xui/en-us/floater_customize.xml @@ -1435,10 +1435,12 @@ one from scratch and wear it.