diff --git a/indra/develop.py b/indra/develop.py index 35b8aa753..03d1b19bd 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -518,9 +518,16 @@ class WindowsSetup(PlatformSetup): self.using_express = True print 'Building with ', self.gens[version]['gen'] , "Express edition" break - else: - print >> sys.stderr, 'Cannot find any Visual Studio installation' - sys.exit(1) + else: + for version in 'vc80 vc90 vc100 vc71'.split(): + if self.find_visual_studio_express_single(version): + self._generator = version + self.using_express = True + print 'Building with ', self.gens[version]['gen'] , "Express edition" + break + else: + print >> sys.stderr, 'Cannot find any Visual Studio installation' + sys.exit(1) return self._generator def _set_generator(self, gen): @@ -605,6 +612,28 @@ class WindowsSetup(PlatformSetup): except WindowsError, err: print >> sys.stderr, "Didn't find ", self.gens[gen]['gen'] return '' + + def find_visual_studio_express_single(self, gen=None): + if gen is None: + gen = self._generator + gen = gen.lower() + try: + import _winreg + key_str = (r'SOFTWARE\Microsoft\VCEXpress\%s_Config\Setup\VC' % + self.gens[gen]['ver']) + value_str = (r'ProductDir') + print ('Reading VS environment from HKEY_CURRENT_USER\%s\%s' % + (key_str, value_str)) + print key_str + + reg = _winreg.ConnectRegistry(None, _winreg.HKEY_CURRENT_USER) + key = _winreg.OpenKey(reg, key_str) + value = _winreg.QueryValueEx(key, value_str)[0]+"IDE" + print 'Found: %s' % value + return value + except WindowsError, err: + print >> sys.stderr, "Didn't find ", self.gens[gen]['gen'] + return '' def get_build_cmd(self): if self.incredibuild: @@ -617,13 +646,15 @@ class WindowsSetup(PlatformSetup): if environment == '': environment = self.find_visual_studio_express() if environment == '': - print >> sys.stderr, "Something went very wrong during build stage, could not find a Visual Studio?" - else: - build_dirs=self.build_dirs() - print >> sys.stderr, "\nSolution generation complete, it can can now be found in:", build_dirs[0] - print >> sys.stderr, "\nAs you are using an Express Visual Studio, the build step cannot be automated" - print >> sys.stderr, "\nPlease see https://wiki.secondlife.com/wiki/Microsoft_Visual_Studio#Extra_steps_for_Visual_Studio_Express_editions for Visual Studio Express specific information" - exit(0) + environment = self.find_visual_studio_express_single() + if environment == '': + print >> sys.stderr, "Something went very wrong during build stage, could not find a Visual Studio?" + else: + build_dirs=self.build_dirs() + print >> sys.stderr, "\nSolution generation complete, it can can now be found in:", build_dirs[0] + print >> sys.stderr, "\nAs you are using an Express Visual Studio, the build step cannot be automated" + print >> sys.stderr, "\nPlease see https://wiki.secondlife.com/wiki/Microsoft_Visual_Studio#Extra_steps_for_Visual_Studio_Express_editions for Visual Studio Express specific information" + exit(0) # devenv.com is CLI friendly, devenv.exe... not so much. return ('"%sdevenv.com" %s.sln /build %s' % diff --git a/indra/llmath/llv4math.h b/indra/llmath/llv4math.h index 5b180b3d7..9a493b267 100644 --- a/indra/llmath/llv4math.h +++ b/indra/llmath/llv4math.h @@ -52,6 +52,8 @@ // // Sorry the code is such a mess. JC +#include "llpreprocessor.h" + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLV4MATH - GNUC diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d06efa9e2..3c39d8919 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -64,6 +64,7 @@ include_directories( ) set(viewer_SOURCE_FILES + llviewerobjectbackup.cpp slfloatermediafilter.cpp floaterlocalassetbrowse.cpp aoremotectrl.cpp @@ -74,7 +75,6 @@ set(viewer_SOURCE_FILES ascentfloatercontactgroups.cpp ascentprefssys.cpp ascentprefsvan.cpp - ascentuploadbrowser.cpp dhparam.cpp dsaparam.cpp emerald.cpp @@ -184,7 +184,6 @@ set(viewer_SOURCE_FILES llfloatereditui.cpp llfloaterenvsettings.cpp llfloaterevent.cpp - llfloaterexport.cpp llfloaterexploreanimations.cpp llfloaterexploresounds.cpp llfloaterfriends.cpp @@ -201,7 +200,6 @@ set(viewer_SOURCE_FILES llfloaterhtmlsimple.cpp llfloaterhud.cpp llfloaterimagepreview.cpp - llfloaterimport.cpp llfloaterinspect.cpp llfloaterjoystick.cpp llfloaterlagmeter.cpp @@ -269,7 +267,6 @@ set(viewer_SOURCE_FILES llhudtext.cpp llhudview.cpp llimpanel.cpp - llimportobject.cpp llimview.cpp llinventoryactions.cpp llinventorybackup.cpp @@ -537,6 +534,7 @@ set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake + llviewerobjectbackup.h slfloatermediafilter.h floaterlocalassetbrowse.h aoremotectrl.h @@ -547,7 +545,6 @@ set(viewer_HEADER_FILES ascentfloatercontactgroups.h ascentprefssys.h ascentprefsvan.h - ascentuploadbrowser.h emerald.h emeraldboobutils.h dofloaterhex.h @@ -656,7 +653,6 @@ set(viewer_HEADER_FILES llfloaterdirectory.h llfloatereditui.h llfloaterenvsettings.h - llfloaterexport.h llfloaterexploreanimations.h llfloaterexploresounds.h llfloaterevent.h @@ -674,7 +670,6 @@ set(viewer_HEADER_FILES llfloaterhtmlsimple.h llfloaterhud.h llfloaterimagepreview.h - llfloaterimport.h llfloaterinspect.h llfloaterjoystick.h llfloaterlagmeter.h @@ -741,7 +736,6 @@ set(viewer_HEADER_FILES llhudtext.h llhudview.h llimpanel.h - llimportobject.h llimview.h llinventorybackup.h llinventorybridge.h @@ -1305,7 +1299,10 @@ add_executable(${VIEWER_BINARY_NAME} MACOSX_BUNDLE ${viewer_SOURCE_FILES} ) -check_message_template(${VIEWER_BINARY_NAME}) + +if (!DISABLE_TEMPLATE_CHECK) + check_message_template(${VIEWER_BINARY_NAME}) +endif (!DISABLE_TEMPLATE_CHECK) if (LLKDU_LIBRARY) add_dependencies(${VIEWER_BINARY_NAME} ${LLKDU_LIBRARY}) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 73555f64b..d2870de2c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9,6 +9,22 @@ settings_rlv.xml + FloaterObjectBackuptRect + + Comment + Rectangle for the object backup floater + Persist + 1 + Type + Rect + Value + + 0 + 0 + 0 + 0 + + MediaEnableFilter diff --git a/indra/newview/ascentuploadbrowser.cpp b/indra/newview/ascentuploadbrowser.cpp deleted file mode 100644 index aaa7638fe..000000000 --- a/indra/newview/ascentuploadbrowser.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/** - * @file ascentuploadbrowser.h - * @Author Duncan Garrett (Hg Beeks) - * Meant as a replacement to using a system file browser for uploads. - * - * Created August 27 2010 - * - * ALL SOURCE CODE IS PROVIDED "AS IS." THE CREATOR MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * k ilu bye - */ - -#include "llviewerprecompiledheaders.h" - -#include "ascentuploadbrowser.h" - -//UI Elements -#include "llbutton.h" //Buttons -#include "llcombobox.h" //Combo dropdowns -#include "llscrolllistctrl.h" //List box for filenames -#include "lluictrlfactory.h" //Loads the XUI - -// project includes -#include "llresmgr.h" -#include "llsdserialize.h" //XML Parsing - Probably not needed -#include "llviewercontrol.h" -#include "llviewerwindow.h" - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- - -LLSD ASFloaterUploadBrowser::mUploaderSettings; -ASFloaterUploadBrowser* ASFloaterUploadBrowser::sInstance = NULL; - - -///---------------------------------------------------------------------------- -/// Class ASFloaterUploadBrowser -///---------------------------------------------------------------------------- - -// Default constructor -ASFloaterUploadBrowser::ASFloaterUploadBrowser() -: LLFloater(std::string("floater_upload_browser"), - std::string("FloaterUploadRect"), - LLStringUtil::null) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_upload_browser.xml"); - - mUploaderSettings.clear(); - mUploaderSettings = gSavedSettings.getLLSD("AscentUploadSettings"); - - mPathName = mUploaderSettings["ActivePath"].asString(); - if (mPathName == "None") - mPathName = gDirUtilp->getExecutableDir(); - mFilterType = "None"; - - - //File list ------------------------------------------------------ - mFileList = getChild("file_list"); - childSetCommitCallback("file_list", onClickFile, this); - childSetDoubleClickCallback("file_list", onDoubleClick); - - //Above File List ------------------------------------------------ - - mBookmarkCombo = getChild("bookmark_combo"); - S32 index; - for (index = 0; index < mUploaderSettings["Bookmarks"].size(); index++) - { - std::string bookmark = mUploaderSettings["Bookmarks"][index].asString(); - if (bookmark != "") - mBookmarkCombo->add(bookmark, ADD_BOTTOM); - } - - mDriveCombo = getChild("drive_combo"); - childSetCommitCallback("drive_combo", onChangeDrives, this); - //This is so unbelievably shitty I can't handle it -HgB - std::string drive_letters[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; //Oh my god it's somehow worse now -HgB - - mDriveCombo->removeall(); - for (index = 0; index < 26; index++) - { - std::string dir = drive_letters[index] + ":"; - S32 file_count = gDirUtilp->countFilesInDir(dir + gDirUtilp->getDirDelimiter(), "*.*"); - if(file_count) - { - mDriveCombo->add(dir, ADD_BOTTOM); - } - } - - childSetAction("directory_button", onClickFilepathGoto, this); - childSetCommitCallback("dir_path", onDirCommit, (void*)this); - //Below File List ------------------------------------------------ - childSetCommitCallback("file_filter_combo", onUpdateFilter, this); - - - refresh(); - mFileList->sortByColumn(std::string("file_name"), TRUE); - mFileList->sortByColumn(std::string("file_type"), TRUE); - childHide("multiple_uploads_label"); - childHide("bad_image_text"); -} - -// Destroys the object -ASFloaterUploadBrowser::~ASFloaterUploadBrowser() -{ - sInstance = NULL; -} - -void ASFloaterUploadBrowser::onDirCommit(LLUICtrl* ctrl, void* data) -{ - ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)data; - if (panelp) - { - panelp->onClickFilepathGoto(data); - } -} - -void ASFloaterUploadBrowser::updateBrowser(void* data, std::string new_path) -{ - ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)data; - if ((new_path != panelp->mPathName)||(new_path == "")) - { - panelp->mPathName = new_path; - panelp->refresh(); - panelp->mFileList->selectFirstItem(); - panelp->childSetValue("asset_name", ""); - } -} - -//static -void ASFloaterUploadBrowser::onClickFilepathGoto(void* data) -{ - ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)data; - std::string new_path = panelp->childGetValue("dir_path"); - panelp->updateBrowser(data, new_path); -} - -void ASFloaterUploadBrowser::onClickFile(LLUICtrl* ctrl, void* user_data) -{ - ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)user_data; - panelp->refreshUploadOptions(); -} - -void ASFloaterUploadBrowser::onChangeDrives(LLUICtrl* ctrl, void* user_data) -{ - ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)user_data; - if (panelp->mDriveCombo->getSelectedValue().asString() != panelp->mFilterType) - { - panelp->updateBrowser(user_data, panelp->mDriveCombo->getSelectedValue().asString()); - } -} - -void ASFloaterUploadBrowser::onUpdateFilter(LLUICtrl* ctrl, void* user_data) -{ - ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)user_data; - LLComboBox* combo = panelp->getChild("file_filter_combo"); - if (combo->getSelectedValue().asString() != panelp->mFilterType) - { - panelp->mFilterType = ""; - panelp->mFilterType = combo->getSelectedValue().asString(); - panelp->updateBrowser(user_data, ""); - } -} - -void ASFloaterUploadBrowser::refreshUploadOptions() -{ - if (!mFileList->isEmpty()) - { - if(!mFileList->getSelectedIDs().count()) - { - llinfos << "No selection, clearing field." << llendl; - childSetValue("asset_name", ""); - } - else - { - if (mFileList->getFirstSelected()->getColumn(LIST_ASSET_TYPE)->getValue().asInteger() == LIST_TYPE_FILE) - { - std::string name; - bool show_tex = false; - bool show_snd = false; - bool show_anm = false; - bool show_multiple = false; - if (mFileList->getAllSelected().size() > 1) - { - - llinfos << "Selected multiple files." << llendl; - name = "(Multiple)"; - show_multiple = true; - /*LLButton* expand_button = getChild("expand_collapse_btn"); - expand_button->setLabelArg("[COST]", std::string(mFileList->getAllSelected().size() * 10));*/ - childSetValue("multiple_uploads_label", "Multiple files selected. Total cost is: " + llformat("%d", mFileList->getAllSelected().size() * 10)); - } - else - { - int type = mFileList->getFirstSelected()->getColumn(LIST_FILE_TYPE)->getValue().asInteger(); - llinfos << "Selected a file, type" << type << llendl; - if (type == FILE_TEXTURE) - { - show_tex = true; - } - else if (type == FILE_SOUND) - { - show_snd = true; - } - else if (type == FILE_ANIMATION) - { - show_anm = true; - } - name = mFileList->getFirstSelected()->getColumn(LIST_FILE_NAME)->getValue().asString(); - - } - childSetVisible("texture_preview_label", (show_tex && !show_multiple)); - childSetVisible("texture_preview_combo", (show_tex && !show_multiple)); - childSetVisible("multiple_uploads_label", show_multiple); - childSetValue("asset_name", name); - } - } - } -} - -void ASFloaterUploadBrowser::onDoubleClick(void* user_data) -{ - ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)user_data; - panelp->handleDoubleClick(); -} - -void ASFloaterUploadBrowser::handleDoubleClick() -{ - if (mFileList->getFirstSelected()->getColumn(LIST_ASSET_TYPE)->getValue().asInteger() == LIST_TYPE_PARENT) - { - S32 dirLimiterIndex = mPathName.find_last_of(gDirUtilp->getDirDelimiter()); - mPathName = mPathName.substr(0, dirLimiterIndex); - refresh(); - mFileList->selectFirstItem(); - } - else if (mFileList->getFirstSelected()->getColumn(LIST_ASSET_TYPE)->getValue().asInteger() == LIST_TYPE_FOLDER) - { - //Make sure that it's an actual folder so you don't get stuck - Specifically meant for files with no extension. -HgB - std::string new_path = mPathName + gDirUtilp->getDirDelimiter() + mFileList->getFirstSelected()->getColumn(LIST_FILE_NAME)->getValue().asString(); - S32 file_count = gDirUtilp->countFilesInDir(new_path, "*.*"); - if(!file_count) - return; - mPathName = mPathName + gDirUtilp->getDirDelimiter() + mFileList->getFirstSelected()->getColumn(LIST_FILE_NAME)->getValue().asString(); - refresh(); - mFileList->selectFirstItem(); - - } - childSetValue("asset_name", ""); -} - -void ASFloaterUploadBrowser::refresh() -{ - std::string filename; - std::string fullPath = mPathName + gDirUtilp->getDirDelimiter(); - mFileList->deselectAllItems(); - mFileList->deleteAllItems(); - childSetValue("dir_path", gDirUtilp->getDirName(fullPath)); - mUploaderSettings["ActivePath"] = mPathName; - gSavedSettings.setLLSD("AscentUploadSettings", mUploaderSettings); - gDirUtilp->getNextFileInDir(gDirUtilp->getChatLogsDir(),"*", filename, false); //Clears the last file - bool found = true; - S32 file_count = 0; - while(found) - { - found = gDirUtilp->getNextFileInDir(fullPath, "*.*", filename, false); - if(found) - { - S32 periodIndex = filename.find_last_of("."); - std::string extension = filename.substr(periodIndex + 1, filename.length() - 1); - std::string extensionL = utf8str_tolower(extension); - LLSD element; - element["path"] = mPathName + filename; - - LLSD& filename_column = element["columns"][LIST_FILE_NAME]; - filename_column["column"] = "file_name"; - filename_column["font"] = "SANSSERIF"; - filename_column["font-style"] = "NORMAL"; - - LLSD& filetype_column = element["columns"][LIST_FILE_TYPE]; - filetype_column["column"] = "file_type"; - filetype_column["type"] = "number"; - - LLSD& assettype_column = element["columns"][LIST_ASSET_TYPE]; - assettype_column["column"] = "asset_type"; - assettype_column["type"] = "number"; - - LLSD& invtype_column = element["columns"][LIST_INVENTORY_TYPE]; - invtype_column["column"] = "icon_inventory_type"; - invtype_column["type"] = "icon"; - invtype_column["value"] = "inv_folder_trash.tga"; - - - if (((extensionL == "jpeg")||(extensionL == "jpg")||(extensionL == "tga") - ||(extensionL == "png")||(extensionL == "bmp"))&&((mFilterType == "None")||(mFilterType == "Texture"))) - { - invtype_column["value"] = "inv_item_texture.tga"; - filename_column["value"] = filename.substr(0, periodIndex); - filetype_column["value"] = FILE_TEXTURE; - assettype_column["value"] = LIST_TYPE_FILE; - - } - else if ((extensionL == "wav")&&((mFilterType == "None")||(mFilterType == "Sound"))) - { - invtype_column["value"] = "inv_item_sound.tga"; - filename_column["value"] = filename.substr(0, periodIndex); - filetype_column["value"] = FILE_SOUND; - assettype_column["value"] = LIST_TYPE_FILE; - } - else if (((extensionL == "bvh")||(extensionL == "anim"))&&((mFilterType == "None")||(mFilterType == "Animation"))) - { - invtype_column["value"] = "inv_item_animation.tga"; - filename_column["value"] = filename.substr(0, periodIndex); - filetype_column["value"] = FILE_ANIMATION; - assettype_column["value"] = LIST_TYPE_FILE; - } - else if ((extension == filename.substr(0, filename.length() - 1))&&(filename != ".")) - { - std::string test_path = mPathName + gDirUtilp->getDirDelimiter() + filename + gDirUtilp->getDirDelimiter(); - S32 file_count = gDirUtilp->countFilesInDir(test_path, "*.*"); - if(file_count) - { - invtype_column["value"] = "inv_folder_plain_closed.tga"; - filename_column["value"] = filename; - filetype_column["value"] = FOLDER; - assettype_column["value"] = LIST_TYPE_FOLDER; - } - } - else if (filename == "..") - { - invtype_column["value"] = "inv_folder_plain_open.tga"; - filename_column["value"] = filename; - filetype_column["value"] = FOLDER; - assettype_column["value"] = LIST_TYPE_PARENT; - } - if (invtype_column["value"].asString() != "inv_folder_trash.tga") - { - mFileList->addElement(element, ADD_BOTTOM); - if (assettype_column["value"].asInteger() == LIST_TYPE_FILE) - { - file_count++; - } - } - } - } - - std::string result; - LLResMgr::getInstance()->getIntegerString(result, file_count); - if (result == "") - result = "0"; - childSetTextArg("result_label", "[COUNT]", result); - - mFileList->sortItems(); - llinfos << "Total files loaded: " << result << "." << llendl; -} - -// static -void ASFloaterUploadBrowser::show(void*) -{ - if (!sInstance) - { - sInstance = new ASFloaterUploadBrowser(); - } - - sInstance->open(); /*Flawfinder: ignore*/ -} \ No newline at end of file diff --git a/indra/newview/ascentuploadbrowser.h b/indra/newview/ascentuploadbrowser.h deleted file mode 100644 index 27a071f8b..000000000 --- a/indra/newview/ascentuploadbrowser.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file ascentuploadbrowser.h - * @Author Duncan Garrett - * Meant as a replacement to using Windows' file browser for uploads. - * - * Created August 27 2010 - * - * ALL SOURCE CODE IS PROVIDED "AS IS." THE CREATOR MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * k ilu bye - */ - -#ifndef ASCENT_UPLOAD_BROWSER -#define ASCENT_UPLOAD_BROWSER - -#include "llfloater.h" -#include "llcombobox.h" - -class LLScrollListCtrl; - -class ASFloaterUploadBrowser : public LLFloater -{ -public: - using LLFloater::handleDoubleClick; - - ASFloaterUploadBrowser(); - virtual ~ASFloaterUploadBrowser(); - //File list - static void onClickFile(LLUICtrl* ctrl, void* user_data); - static void onUpdateFilter(LLUICtrl* ctrl, void* user_data); - static void onDoubleClick(void* user_data); - static void onDirCommit (LLUICtrl* ctrl, void* data); - static void onChangeDrives(LLUICtrl* ctrl, void* user_data); - static void onClickFilepathGoto(void* data); - - void updateBrowser(void* data, std::string new_path); - void refresh(); - void refreshUploadOptions(); - void handleDoubleClick(); - static void show(void*); - - std::vector datas; - -private: - static LLSD mUploaderSettings; - static ASFloaterUploadBrowser* sInstance; - enum FILE_COLUMN_ORDER - { - LIST_FILE_TYPE, - LIST_ASSET_TYPE, - LIST_INVENTORY_TYPE, - LIST_FILE_NAME, - LIST_DATA - }; - enum FILE_TYPE_ORDER - { - LIST_TYPE_PARENT, - LIST_TYPE_FOLDER, - LIST_TYPE_FILE - }; - enum FILE_TYPE - { - FOLDER, - FILE_TEXTURE, - FILE_SOUND, - FILE_ANIMATION - }; - LLScrollListCtrl* mFileList; - LLComboBox* mDriveCombo; - LLComboBox* mBookmarkCombo; - - std::string mPathName; - std::string mFilterType; -}; - - -#endif // ASCENT_UPLOAD_BROWSER diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index 337cf1956..f4f52eb73 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -581,10 +581,26 @@ void LLPanelEditWearable::setSubpart( ESubpart subpart ) item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem(mType); 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 <= 18) // 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 = ((perm_mask & PERM_MODIFY) && is_complete) ? TRUE : FALSE; @@ -608,7 +624,8 @@ void LLPanelEditWearable::setSubpart( ESubpart subpart ) } gFloaterCustomize->generateVisualParamHints(NULL, sorted_params); gFloaterCustomize->updateScrollingPanelUI(); - + gFloaterCustomize->childSetEnabled("Export", can_export); + gFloaterCustomize->childSetEnabled("Import", can_import); // Update the camera gMorphView->setCameraTargetJoint( gAgent.getAvatarObject()->getJoint( part->mTargetJoint ) ); @@ -1700,17 +1717,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 +1790,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;csetVisualParamWeight( 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 ) { diff --git a/indra/newview/llfloatercustomize.h b/indra/newview/llfloatercustomize.h index 28a525e4f..5648cc6af 100644 --- a/indra/newview/llfloatercustomize.h +++ b/indra/newview/llfloatercustomize.h @@ -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 ); diff --git a/indra/newview/llfloaterexport.cpp b/indra/newview/llfloaterexport.cpp deleted file mode 100644 index 70d229f1a..000000000 --- a/indra/newview/llfloaterexport.cpp +++ /dev/null @@ -1,906 +0,0 @@ -// - -#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 "llviewerimagelist.h" -#include "lltexturecache.h" -#include "llimage.h" -#include "llappviewer.h" -#include "llimagej2c.h" - -std::vector 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"<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 "<save(mFilename)) - { - llinfos << "FAIL saving texture "< mFormattedImage; - LLUUID mID; - std::string mFilename; -}; - - -LLExportable::LLExportable(LLViewerObject* object, std::string name, std::map& primNameMap) -: mObject(object), - mType(EXPORTABLE_OBJECT), - mPrimNameMap(&primNameMap) -{ -} - -LLExportable::LLExportable(LLVOAvatar* avatar, EWearableType type, std::map& primNameMap) -: mAvatar(avatar), - mType(EXPORTABLE_WEARABLE), - mWearableType(type), - mPrimNameMap(&primNameMap) -{ -} - -LLSD LLExportable::asLLSD() -{ - if(mType == EXPORTABLE_OBJECT) - { - std::list 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::iterator prim_iter = prims.begin(); - std::list::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::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 ) - { - LLViewerImage* 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::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("export_list"); - - std::map 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::iterator avatar_iter = avatars.begin(); - std::map::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("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 ) - { - LLViewerImage* 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("export_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::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("export_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::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("export_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::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("export_list"); - std::vector items = list->getAllData(); - LLSD sd; - std::vector::iterator item_iter = items.begin(); - std::vector::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("export_list"); - std::vector items = list->getAllData(); - int item_count = 0; - LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID(); - bool all_same_avatarid = true; - std::vector::iterator item_iter = items.begin(); - std::vector::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 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); - - 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("export_list"); - S32 item_index = list->getItemIndex(fullid); - if(item_index != -1) - { - std::vector items = list->getAllData(); - std::vector::iterator iter = items.begin(); - std::vector::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::iterator iter = LLFloaterExport::instances.begin(); - std::vector::iterator end = LLFloaterExport::instances.end(); - for( ; iter != end; ++iter) - { - (*iter)->receivePrimName(object, name); - } -} - -// diff --git a/indra/newview/llfloaterexport.h b/indra/newview/llfloaterexport.h deleted file mode 100644 index e5f1028c5..000000000 --- a/indra/newview/llfloaterexport.h +++ /dev/null @@ -1,114 +0,0 @@ -// -#ifndef LL_LLFLOATEREXPORT_H -#define LL_LLFLOATEREXPORT_H - -#include "llfloater.h" -#include "llselectmgr.h" -#include "llvoavatar.h" -#include "llvoavatardefines.h" - -//class LLExportObject -//{ -//public: -// LLExportObject(LLViewerObject* object); -// //LLExportObject(LLViewerObject* object, std::string name); -// -// LLSD asLLSD(); -// -// LLViewerObject* mObject; -//}; -// -//class LLExportWearable -//{ -//public: -// LLExportWearable(LLVOAvatar* avatar, EWearableType type); -// -// LLSD asLLSD(); -// std::string getIcon(); -// -// LLVOAvatar* mAvatar; -// EWearableType mType; -// std::string mName; -//}; -// -// -//class LLExportBakedWearable // not used -//{ -//public: -// LLExportBakedWearable(LLVOAvatar* avatar, EWearableType type); -// -// LLSD asLLSD(); -// std::string getIcon(); -// -// LLVOAvatar* mAvatar; -// EWearableType mType; -// std::string mName; -//}; - - - -class LLExportable -{ - enum EXPORTABLE_TYPE - { - EXPORTABLE_OBJECT, - EXPORTABLE_WEARABLE - }; - -public: - LLExportable(LLViewerObject* object, std::string name, std::map& primNameMap); - LLExportable(LLVOAvatar* avatar, EWearableType type, std::map& primNameMap); - - LLSD asLLSD(); - - EXPORTABLE_TYPE mType; - EWearableType mWearableType; - LLViewerObject* mObject; - LLVOAvatar* mAvatar; - std::map* mPrimNameMap; -}; - - -class LLFloaterExport -: public LLFloater -{ -public: - LLFloaterExport(); - BOOL postBuild(void); - void addAvatarStuff(LLVOAvatar* avatarp); - void updateNamesProgress(); - void receivePrimName(LLViewerObject* object, std::string name); - - LLSD getLLSD(); - - std::vector mPrimList; - std::map mPrimNameMap; - - static std::vector instances; // for callback-type use - - static void receiveObjectProperties(LLUUID fullid, std::string name, std::string desc); - - static void onClickSelectAll(void* user_data); - static void onClickSelectObjects(void* user_data); - static void onClickSelectWearables(void* user_data); - static void onClickSaveAs(void* user_data); - static void onClickMakeCopy(void* user_data); - -private: - virtual ~LLFloaterExport(); - void addToPrimList(LLViewerObject* object); - - enum LIST_COLUMN_ORDER - { - LIST_CHECKED, - LIST_TYPE, - LIST_NAME, - LIST_AVATARID - }; - - LLObjectSelectionHandle mSelection; - std::map mExportables; -}; - -#endif -// diff --git a/indra/newview/llfloaterimport.cpp b/indra/newview/llfloaterimport.cpp deleted file mode 100644 index b2c248f48..000000000 --- a/indra/newview/llfloaterimport.cpp +++ /dev/null @@ -1,363 +0,0 @@ -// -/** - * @file llfloaterimport.cpp - */ - -#include "llviewerprecompiledheaders.h" -#include "llimportobject.h" -#include "llsdserialize.h" -#include "llsdutil.h" -#include "llviewerobject.h" -#include "llagent.h" -#include "llchat.h" -#include "llfloaterchat.h" -#include "llfloater.h" -#include "lllineeditor.h" -#include "llinventorymodel.h" -#include "lluictrlfactory.h" -#include "llscrolllistctrl.h" -#include "llfloaterimport.h" -#include "llimportobject.h" - -LLFloaterImportProgress* LLFloaterImportProgress::sInstance; - -LLFloaterXmlImportOptions::LLFloaterXmlImportOptions(LLXmlImportOptions* default_options) -: mDefaultOptions(default_options) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_import_options.xml"); -} - -BOOL LLFloaterXmlImportOptions::postBuild() -{ - center(); - LLScrollListCtrl* list = getChild("import_list"); - // Add all wearables to list and keep an id:ptr map - std::vector::iterator wearable_end = mDefaultOptions->mWearables.end(); - for(std::vector::iterator iter = mDefaultOptions->mWearables.begin(); - iter != wearable_end; ++iter) - { - LLImportWearable* wearablep = (*iter); - LLUUID id; id.generate(); - mImportWearableMap[id] = wearablep; - LLSD element; - element["id"] = id; - 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_" + LLWearable::typeToTypeName((EWearableType)(wearablep->mType)) + ".tga"; - LLSD& name_column = element["columns"][LIST_NAME]; - name_column["column"] = "name"; - name_column["value"] = wearablep->mName; - list->addElement(element, ADD_BOTTOM); - } - // Add all root objects to list and keep an id:ptr map - std::vector::iterator object_end = mDefaultOptions->mRootObjects.end(); - for(std::vector::iterator iter = mDefaultOptions->mRootObjects.begin(); - iter != object_end; ++iter) - { - LLImportObject* objectp = (*iter); - LLUUID id; id.generate(); - mImportObjectMap[id] = objectp; - LLSD element; - element["id"] = id; - 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"; - name_column["value"] = objectp->mPrimName; - list->addElement(element, ADD_BOTTOM); - } - // Callbacks - childSetAction("select_all_btn", onClickSelectAll, this); - childSetAction("select_objects_btn", onClickSelectObjects, this); - childSetAction("select_wearables_btn", onClickSelectWearables, this); - childSetAction("ok_btn", onClickOK, this); - childSetAction("cancel_btn", onClickCancel, this); - return TRUE; -} - -void LLFloaterXmlImportOptions::onClickSelectAll(void* user_data) -{ - LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data; - LLScrollListCtrl* list = floaterp->getChild("import_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::iterator items_end = items.end(); - bool new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue()); - for( ; item_iter != items_end; ++item_iter) - { - (*item_iter)->getColumn(LIST_CHECKED)->setValue(new_value); - } -} - -void LLFloaterXmlImportOptions::onClickSelectObjects(void* user_data) -{ - LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data; - LLScrollListCtrl* list = floaterp->getChild("import_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::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") - (*item_iter)->getColumn(LIST_CHECKED)->setValue(new_value); - } -} - -void LLFloaterXmlImportOptions::onClickSelectWearables(void* user_data) -{ - LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data; - LLScrollListCtrl* list = floaterp->getChild("import_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::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") - (*item_iter)->getColumn(LIST_CHECKED)->setValue(new_value); - } -} - -void LLFloaterXmlImportOptions::onClickOK(void* user_data) -{ - LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data; - LLXmlImportOptions* opt = new LLXmlImportOptions(floaterp->mDefaultOptions); - opt->clear(); - opt->mReplaceTexture = floaterp->childGetValue("upload_textures"); - LLScrollListCtrl* list = floaterp->getChild("import_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_end = items.end(); - std::vector::iterator child_end = floaterp->mDefaultOptions->mChildObjects.end(); - std::list textures; - for(std::vector::iterator iter = items.begin(); iter != item_end; ++iter) - { - if((*iter)->getColumn(LIST_CHECKED)->getValue()) - { // checked - LLUUID id = (*iter)->getUUID(); - 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::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::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); - } - } - } - } - opt->mKeepPosition = floaterp->childGetValue("keep_position_check"); - LLXmlImport::import(opt); - floaterp->close(); -} - -void LLFloaterXmlImportOptions::onClickCancel(void* user_data) -{ - LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data; - floaterp->close(); -} - -LLFloaterImportProgress::LLFloaterImportProgress() -: LLFloater("ImportProgress", LLRect(0, 130, 400, 0), "Import progress") -{ - 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); - - border = new LLViewBorder( - "CreatedBorder", - LLRect(4, 79, 395, 60)); - addChild(border); - - line = new LLLineEditor( - std::string("Edited"), - LLRect(4, 55, 396, 35), - std::string("Edited prims")); - line->setEnabled(FALSE); - addChild(line); - - border = new LLViewBorder( - "EditedBorder", - LLRect(4, 54, 395, 35)); - addChild(border); - - LLButton* button = new LLButton( - "CancelButton", - LLRect(300, 28, 394, 8)); - button->setLabel(std::string("Cancel")); - button->setEnabled(TRUE); - addChild(button); - childSetAction("CancelButton", LLXmlImport::Cancel, this); - - sInstance = this; -} - -LLFloaterImportProgress::~LLFloaterImportProgress() -{ - sInstance = NULL; -} - -void LLFloaterImportProgress::close(bool app_quitting) -{ - LLXmlImport::sImportInProgress = false; - LLFloater::close(app_quitting); -} - -// static -void LLFloaterImportProgress::show() -{ - if(!sInstance) - sInstance = new LLFloaterImportProgress(); - sInstance->open(); - sInstance->center(); -} - -// static -void LLFloaterImportProgress::update() -{ - if(sInstance) - { - 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)); - create_width *= F32(create_done); - bool create_finished = create_done >= create_goal; - - int edit_goal = create_goal; - int edit_done = LLXmlImport::sPrimIndex; - F32 edit_width = F32(390.f / F32(edit_goal)); - edit_width *= edit_done; - bool edit_finished = edit_done >= edit_goal; - - int attach_goal = (int)LLXmlImport::sId2attachpt.size(); - int attach_done = LLXmlImport::sAttachmentsDone; - F32 attach_width = F32(390.f / F32(attach_goal)); - attach_width *= F32(attach_done); - bool attach_finished = attach_done >= attach_goal; - - bool all_finished = upload_finished && create_finished && edit_finished && attach_finished; - - std::string title; - title.assign(all_finished ? "Imported " : "Importing "); - title.append(LLXmlImport::sXmlImportOptions->mName); - 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("Uploaded"); - text->setText(uploaded_text); - - text = floater->getChild("Created"); - text->setText(created_text); - - text = floater->getChild("Edited"); - text->setText(edited_text); - - LLViewBorder* border = floater->getChild("UploadedBorder"); - border->setRect(LLRect(4, 104, 4 + upload_width, 85)); - - border = floater->getChild("CreatedBorder"); - border->setRect(LLRect(4, 79, 4 + create_width, 60)); - - border = floater->getChild("EditedBorder"); - border->setRect(LLRect(4, 54, 4 + edit_width, 35)); - - LLButton* button = floater->getChild("CancelButton"); - button->setEnabled(!all_finished); - } -} - -// diff --git a/indra/newview/llfloaterimport.h b/indra/newview/llfloaterimport.h deleted file mode 100644 index 31604cd37..000000000 --- a/indra/newview/llfloaterimport.h +++ /dev/null @@ -1,51 +0,0 @@ -// -/** - * @file llfloaterimport.h - */ - -#ifndef LL_LLFLOATERIMPORT_H -#define LL_LLFLOATERIMPORT_H - -#include "llviewerobject.h" -#include "llfloater.h" -#include "llimportobject.h" - - -class LLFloaterImportProgress -: public LLFloater -{ -public: - void close(bool app_quitting); - static LLFloaterImportProgress* sInstance; - static void show(); - static void update(); -private: - LLFloaterImportProgress(); - virtual ~LLFloaterImportProgress(); -}; - - -class LLFloaterXmlImportOptions : public LLFloater -{ -public: - LLFloaterXmlImportOptions(LLXmlImportOptions* default_options); - BOOL postBuild(); - LLXmlImportOptions* mDefaultOptions; - std::map mImportWearableMap; - std::map mImportObjectMap; -private: - enum LIST_COLUMN_ORDER - { - LIST_CHECKED, - LIST_TYPE, - LIST_NAME, - }; - static void onClickSelectAll(void* user_data); - static void onClickSelectObjects(void* user_data); - static void onClickSelectWearables(void* user_data); - static void onClickOK(void* user_data); - static void onClickCancel(void* user_data); -}; - -#endif -// diff --git a/indra/newview/llimportobject.cpp b/indra/newview/llimportobject.cpp deleted file mode 100644 index 2378ee160..000000000 --- a/indra/newview/llimportobject.cpp +++ /dev/null @@ -1,1210 +0,0 @@ - -// -/** - * @file llimportobject.cpp - */ - -#include "llviewerprecompiledheaders.h" -#include "llimportobject.h" -#include "llsdserialize.h" -#include "llsdutil_math.h" -#include "llviewerobject.h" -#include "llagent.h" -#include "llchat.h" -#include "llfloaterchat.h" -#include "llfloater.h" -#include "lllineeditor.h" -#include "llinventorymodel.h" -#include "lluictrlfactory.h" -#include "llscrolllistctrl.h" -#include "llviewercontrol.h" -#include "llfloaterimport.h" -#include "llassetuploadresponders.h" -#include "lleconomy.h" -#include "llfloaterperms.h" -#include "llviewerregion.h" -#include "llviewerobjectlist.h" -#include "llimagej2c.h" - -// static vars -bool LLXmlImport::sImportInProgress = false; -bool LLXmlImport::sImportHasAttachments = false; -LLUUID LLXmlImport::sFolderID; -LLViewerObject* LLXmlImport::sSupplyParams; -int LLXmlImport::sPrimsNeeded; -std::vector LLXmlImport::sPrims; -std::map LLXmlImport::sId2attachpt; -std::map LLXmlImport::sPt2watch; -std::map LLXmlImport::sPt2attachpos; -std::map LLXmlImport::sPt2attachrot; -std::map > LLXmlImport::sLinkSets; -int LLXmlImport::sPrimIndex = 0; -int LLXmlImport::sAttachmentsDone = 0; -std::map LLXmlImport::sId2localid; -std::map LLXmlImport::sRootpositions; -std::map LLXmlImport::sRootrotations; -LLXmlImportOptions* LLXmlImport::sXmlImportOptions; -std::map LLXmlImport::sTextureReplace; -int LLXmlImport::sTotalAssets = 0; -int LLXmlImport::sUploadedAssets = 0; -// timer for watching link -class LLLinkTimer : public LLEventTimer -{ -public: - LLLinkTimer(std::vector roots) : LLEventTimer(0.1f) - { - mOptions = LLXmlImport::sXmlImportOptions; - mRoots = roots; - } - virtual BOOL tick() - { - // Import for this timer has been cancled :< - if(!LLXmlImport::sImportInProgress || (LLXmlImport::sXmlImportOptions && mOptions && mOptions != LLXmlImport::sXmlImportOptions)) return TRUE; - // LET US CONTINUE - std::vector unlinked_roots; - for(std::vector::iterator itr = mRoots.begin();itr != mRoots.end();itr++) - { - LLViewerObject* object = gObjectList.findObject((*itr)); - if(object) - { - if(object->numChildren() == 0) - { - llinfos << "WAIT " << (*itr).asString() << llendl; - unlinked_roots.push_back((*itr)); - - } - } - } - if(unlinked_roots.size() > 0) - { - mRoots = unlinked_roots; - return FALSE; - } - else - { - LLXmlImport::finish_link(); - return TRUE; - } - } - -protected: - LLXmlImportOptions* mOptions; - std::vector mRoots; -}; -bool operator==(const LLXmlImportOptions &a, const LLXmlImportOptions &b) -{ - return (a.mID == b.mID); -} - -bool operator!=(const LLXmlImportOptions &a, const LLXmlImportOptions &b) -{ - return (a.mID != b.mID); -} -LLXmlImportOptions::LLXmlImportOptions(LLXmlImportOptions* options) -{ - mName = options->mName; - mRootObjects = options->mRootObjects; - mChildObjects = options->mChildObjects; - mWearables = options->mWearables; - mSupplier = options->mSupplier; - mKeepPosition = options->mKeepPosition; - mAssetDir = options->mAssetDir; - mID = options->mID; -} -LLXmlImportOptions::LLXmlImportOptions(std::string filename) -: mSupplier(NULL), - mKeepPosition(FALSE) -{ - mName = gDirUtilp->getBaseFileName(filename, true); - llifstream in(filename); - if(!in.is_open()) - { - llwarns << "Couldn't open file..." << llendl; - return; - } - LLSD llsd; - if(LLSDSerialize::fromXML(llsd, in) < 1) - { - llwarns << "Messed up data?" << llendl; - return; - } - mAssetDir = filename.substr(0,filename.find_last_of(".")) + "_assets"; - init(llsd); -} -LLXmlImportOptions::LLXmlImportOptions(LLSD llsd) -: mName("stuff"), - mSupplier(NULL), - mKeepPosition(FALSE) -{ - 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) -{ - clear(); - // Separate objects and wearables - std::vector unsorted_objects; - LLSD::map_iterator map_end = llsd.endMap(); - for(LLSD::map_iterator map_iter = llsd.beginMap() ; map_iter != map_end; ++map_iter) - { - std::string key((*map_iter).first); - LLSD item = (*map_iter).second; - if(item.has("type")) - { - if(item["type"].asString() == "wearable") - mWearables.push_back(new LLImportWearable(item)); - else - unsorted_objects.push_back(new LLImportObject(key, item)); - } - else // assumed to be a prim - unsorted_objects.push_back(new LLImportObject(key, item)); - } - // Separate roots from children - int total_objects = (int)unsorted_objects.size(); - for(int i = 0; i < total_objects; i++) - { - if(unsorted_objects[i]->mParentId == "") - mRootObjects.push_back(unsorted_objects[i]); - else - mChildObjects.push_back(unsorted_objects[i]); - } - - mID.generate(); - -} -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 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 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++; - if(!LLXmlImport::sImportInProgress) return; - 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 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 ) -{ - std::string r = llformat( "%.2f", f ); - // "1.20" -> "1.2" - // "24.00" -> "24." - S32 len = r.length(); - while( len > 0 && '0' == r[len - 1] ) - { - r.erase(len-1, 1); - len--; - } - if( '.' == r[len - 1] ) - { - // "24." -> "24" - r.erase(len-1, 1); - } - else if( ('-' == r[0]) && ('0' == r[1]) ) - { - // "-0.59" -> "-.59" - r.erase(1, 1); - } - else if( '0' == r[0] ) - { - // "0.59" -> ".59" - r.erase(0, 1); - } - return r; -} - -LLImportWearable::LLImportWearable(LLSD sd) -{ - mOrginalLLSD = sd; - 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) - { - mTextures.push_back((*map_iter).second); - mData += (*map_iter).first + " " + (*map_iter).second.asString() + "\n"; - } -} -void LLImportWearable::replaceTextures(std::map 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::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), -// mParentId(parentId), -// mPrimName("Object") -//{ -// importIsAttachment = false; -//} -LLImportObject::LLImportObject(std::string id, LLSD prim) - : LLViewerObject(LLUUID::null, 9, NULL, TRUE) -{ - importIsAttachment = false; - mId = id; - mParentId = ""; - mPrimName = "Object"; - if(prim.has("parent")) - { - mParentId = prim["parent"].asString(); - } - // Stuff for attach - if(prim.has("attach")) - { - importIsAttachment = true; - importAttachPoint = (U8)prim["attach"].asInteger(); - importAttachPos = ll_vector3_from_sd(prim["position"]); - importAttachRot = ll_quaternion_from_sd(prim["rotation"]); - } - // Transforms - setPosition(ll_vector3_from_sd(prim["position"]), FALSE); - setScale(ll_vector3_from_sd(prim["scale"]), FALSE); - setRotation(ll_quaternion_from_sd(prim["rotation"]), FALSE); - // Flags - setFlags(FLAGS_CAST_SHADOWS, prim["shadows"].asInteger()); - setFlags(FLAGS_PHANTOM, prim["phantom"].asInteger()); - setFlags(FLAGS_USE_PHYSICS, prim["physical"].asInteger()); - // Volume params - LLVolumeParams volume_params; - volume_params.fromLLSD(prim["volume"]); - - setVolume(volume_params, 0, false); - // Extra params - if(prim.has("flexible")) - { - LLFlexibleObjectData* wat = new LLFlexibleObjectData(); - wat->fromLLSD(prim["flex"]); - LLFlexibleObjectData flex = *wat; - setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, flex, true); - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true); - } - if(prim.has("light")) - { - LLLightParams* wat = new LLLightParams(); - wat->fromLLSD(prim["light"]); - LLLightParams light = *wat; - setParameterEntry(LLNetworkData::PARAMS_LIGHT, light, true); - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true); - } - if(prim.has("sculpt")) - { - LLSculptParams *wat = new LLSculptParams(); - wat->fromLLSD(prim["sculpt"]); - LLSculptParams sculpt = *wat; - setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt, true); - setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, true); - } - // Textures - LLSD textures = prim["textures"]; - LLSD::array_iterator array_iter = textures.beginArray(); - LLSD::array_iterator array_end = textures.endArray(); - int i = 0; - for( ; array_iter != array_end; ++array_iter) - { - 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(); - } -} - -void LLXmlImport::rez_supply() -{ - if(sImportInProgress && sXmlImportOptions && (sPrimsNeeded > 0)) - { - sPrimsNeeded--; - // Need moar prims - if(sXmlImportOptions->mSupplier == NULL) - { - gMessageSystem->newMessageFast(_PREHASH_ObjectAdd); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU8Fast(_PREHASH_PCode, 9); - gMessageSystem->addU8Fast(_PREHASH_Material, LL_MCODE_WOOD); - gMessageSystem->addU32Fast(_PREHASH_AddFlags, 0); - gMessageSystem->addU8Fast(_PREHASH_PathCurve, 16); - gMessageSystem->addU8Fast(_PREHASH_ProfileCurve, 1); - gMessageSystem->addU16Fast(_PREHASH_PathBegin, 0); - gMessageSystem->addU16Fast(_PREHASH_PathEnd, 0); - gMessageSystem->addU8Fast(_PREHASH_PathScaleX, 100); - gMessageSystem->addU8Fast(_PREHASH_PathScaleY, 100); - gMessageSystem->addU8Fast(_PREHASH_PathShearX, 0); - gMessageSystem->addU8Fast(_PREHASH_PathShearY, 0); - gMessageSystem->addS8Fast(_PREHASH_PathTwist, 0); - gMessageSystem->addS8Fast(_PREHASH_PathTwistBegin, 0); - gMessageSystem->addS8Fast(_PREHASH_PathRadiusOffset, 0); - gMessageSystem->addS8Fast(_PREHASH_PathTaperX, 0); - gMessageSystem->addS8Fast(_PREHASH_PathTaperY, 0); - gMessageSystem->addU8Fast(_PREHASH_PathRevolutions, 0); - gMessageSystem->addS8Fast(_PREHASH_PathSkew, 0); - gMessageSystem->addU16Fast(_PREHASH_ProfileBegin, 0); - gMessageSystem->addU16Fast(_PREHASH_ProfileEnd, 0); - gMessageSystem->addU16Fast(_PREHASH_ProfileHollow, 0); - gMessageSystem->addU8Fast(_PREHASH_BypassRaycast, 1); - - LLVector3 rezpos = gAgent.getPositionAgent() + LLVector3(0.0f, 0.0f, 2.0f); - - gMessageSystem->addVector3Fast(_PREHASH_RayStart, rezpos); - gMessageSystem->addVector3Fast(_PREHASH_RayEnd, rezpos); - gMessageSystem->addUUIDFast(_PREHASH_RayTargetID, LLUUID::null); - gMessageSystem->addU8Fast(_PREHASH_RayEndIsIntersection, 0); - gMessageSystem->addVector3Fast(_PREHASH_Scale, sSupplyParams->getScale()); - gMessageSystem->addQuatFast(_PREHASH_Rotation, LLQuaternion::DEFAULT); - gMessageSystem->addU8Fast(_PREHASH_State, 0); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - } - else // have supplier - { - gMessageSystem->newMessageFast(_PREHASH_ObjectDuplicate); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); - gMessageSystem->nextBlockFast(_PREHASH_SharedData); - - LLVector3 rezpos = gAgent.getPositionAgent() + LLVector3(0.0f, 0.0f, 2.0f); - rezpos -= sSupplyParams->getPositionRegion(); - - gMessageSystem->addVector3Fast(_PREHASH_Offset, rezpos); - gMessageSystem->addU32Fast(_PREHASH_DuplicateFlags, 0); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, sXmlImportOptions->mSupplier->getLocalID()); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - } - LLFloaterImportProgress::update(); - } -} - - -// static -void LLXmlImport::import(LLXmlImportOptions* import_options) -{ - 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* - if(throttle < 128000.) - { - gMessageSystem->mPacketRing.setOutBandwidth(128000.0); - } - gMessageSystem->mPacketRing.setUseOutThrottle(TRUE); - - sXmlImportOptions = import_options; - if(sXmlImportOptions->mSupplier == NULL) - { - LLViewerObject* cube = new LLViewerObject(LLUUID::null, 9, NULL, TRUE); - cube->setScale(LLVector3(.31337f, .31337f, .31337f), FALSE); - sSupplyParams = cube; - } - else sSupplyParams = sXmlImportOptions->mSupplier; - - if(!(sXmlImportOptions->mKeepPosition) && sXmlImportOptions->mRootObjects.size()) - { // Reposition all roots so that the first root is somewhere near the avatar - // Find the root closest to the ground - int num_roots = (int)sXmlImportOptions->mRootObjects.size(); - int lowest_root = 0; - F32 lowest_z(65536.f); - for(int i = 0; i < num_roots; i++) - { - F32 z = sXmlImportOptions->mRootObjects[i]->getPosition().mV[2]; - if(z < lowest_z) - { - lowest_root = i; - lowest_z = z; - } - } - // Move all roots - LLVector3 old_pos = sXmlImportOptions->mRootObjects[lowest_root]->getPosition(); - LLVector3 new_pos = gAgent.getPositionAgent() + (gAgent.getAtAxis() * 2.0f); - LLVector3 difference = new_pos - old_pos; - for(int i = 0; i < num_roots; i++) - { - sXmlImportOptions->mRootObjects[i]->setPosition(sXmlImportOptions->mRootObjects[i]->getPosition() + difference, FALSE); - } - } - - // Make the actual importable list - sPrims.clear(); - // Clear these attachment-related maps - sPt2watch.clear(); - sId2attachpt.clear(); - sPt2attachpos.clear(); - sPt2attachrot.clear(); - // Go ahead and add roots first - std::vector::iterator root_iter = sXmlImportOptions->mRootObjects.begin(); - std::vector::iterator root_end = sXmlImportOptions->mRootObjects.end(); - for( ; root_iter != root_end; ++root_iter) - { - sPrims.push_back(*root_iter); - // Remember some attachment info - if((*root_iter)->importIsAttachment) - { - sId2attachpt[(*root_iter)->mId] = (*root_iter)->importAttachPoint; - sPt2watch[(*root_iter)->importAttachPoint] = true; - sPt2attachpos[(*root_iter)->importAttachPoint] = (*root_iter)->importAttachPos; - sPt2attachrot[(*root_iter)->importAttachPoint] = (*root_iter)->importAttachRot; - } - } - // Then add children, nearest first - std::vector children(sXmlImportOptions->mChildObjects); - for(root_iter = sXmlImportOptions->mRootObjects.begin() ; root_iter != root_end; ++root_iter) - { - while(children.size() > 0) - { - std::string rootid = (*root_iter)->mId; - F32 lowest_mag = 65536.0f; - std::vector::iterator lowest_child_iter = children.begin(); - LLImportObject* lowest_child = (*lowest_child_iter); - - std::vector::iterator child_end = children.end(); - for(std::vector::iterator child_iter = children.begin() ; child_iter != child_end; ++child_iter) - { - if((*child_iter)->mParentId == rootid) - { - F32 mag = (*child_iter)->getPosition().magVec(); - if(mag < lowest_mag) - { - lowest_child_iter = child_iter; - lowest_child = (*lowest_child_iter); - lowest_mag = mag; - } - } - } - sPrims.push_back(lowest_child); - children.erase(lowest_child_iter); - } - } - - sImportInProgress = true; - sImportHasAttachments = (sId2attachpt.size() > 0); - sPrimsNeeded = (int)sPrims.size(); - sTotalAssets = sXmlImportOptions->mAssets.size(); - sPrimIndex = 0; - sUploadedAssets = 0; - sId2localid.clear(); - sRootpositions.clear(); - sRootrotations.clear(); - sLinkSets.clear(); - - LLFloaterImportProgress::show(); - LLFloaterImportProgress::update(); - - // Create folder - 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 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; - tid.generate(); - // Create asset - gMessageSystem->newMessageFast(_PREHASH_AssetUploadRequest); - gMessageSystem->nextBlockFast(_PREHASH_AssetBlock); - gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid); - gMessageSystem->addS8Fast(_PREHASH_Type, (S8)at); - gMessageSystem->addBOOLFast(_PREHASH_Tempfile, FALSE); - gMessageSystem->addBOOLFast(_PREHASH_StoreLocal, FALSE); - gMessageSystem->addStringFast(_PREHASH_AssetData, sXmlImportOptions->mWearables[i]->mData.c_str()); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - // Create item - gMessageSystem->newMessageFast(_PREHASH_CreateInventoryItem); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_InventoryBlock); - gMessageSystem->addU32Fast(_PREHASH_CallbackID, 0); - gMessageSystem->addUUIDFast(_PREHASH_FolderID, sFolderID); - gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid); - gMessageSystem->addU32Fast(_PREHASH_NextOwnerMask, 532480); - gMessageSystem->addS8Fast(_PREHASH_Type, at); - gMessageSystem->addS8Fast(_PREHASH_InvType, 18); - gMessageSystem->addS8Fast(_PREHASH_WearableType, sXmlImportOptions->mWearables[i]->mType); - gMessageSystem->addStringFast(_PREHASH_Name, sXmlImportOptions->mWearables[i]->mName.c_str()); - gMessageSystem->addStringFast(_PREHASH_Description, ""); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - } - // Go ahead and upload asset data - rez_supply(); -} -// static -void LLXmlImport::onNewPrim(LLViewerObject* object) -{ - - - int currPrimIndex = sPrimIndex++; - - if(currPrimIndex >= (int)sPrims.size()) - { - if(sAttachmentsDone >= (int)sPt2attachpos.size()) - { - // "stop calling me" - sImportInProgress = false; - return; - } - } - - LLImportObject* from = sPrims[currPrimIndex]; - - // Flags - // trying this first in case it helps when supply is physical... - U32 flags = from->mFlags; - flags = flags & (~FLAGS_USE_PHYSICS); - object->setFlags(flags, TRUE); - object->setFlags(~flags, FALSE); // Can I improve this lol? - if(from->mParentId == "") - { - // this will be a root - sId2localid[from->mId] = object->getLocalID(); - sRootpositions[object->getLocalID()] = from->getPosition(); - sRootrotations[object->getLocalID()] = from->getRotation(); - // If it's an attachment, set description - if(from->importIsAttachment) - { - gMessageSystem->newMessageFast(_PREHASH_ObjectDescription); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_LocalID, object->getLocalID()); - gMessageSystem->addStringFast(_PREHASH_Description, from->mId); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - } - } - else - { - //make positions and rotations offset from the root prim. - U32 parentlocalid = sId2localid[from->mParentId]; - from->setPosition((from->getPosition() * sRootrotations[parentlocalid]) + sRootpositions[parentlocalid]); - from->setRotation(from->getRotation() * sRootrotations[parentlocalid]); - sLinkSets[parentlocalid].push(object->getLocalID()); //this is here so we dont get 1 prim objects into the linkset queue - - } - // Volume params - LLVolumeParams params = from->getVolume()->getParams(); - object->setVolume(params, 0, false); - object->sendShapeUpdate(); - // Extra params - if(from->isFlexible()) - { - LLFlexibleObjectData flex = *((LLFlexibleObjectData*)from->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE)); - object->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, flex, true); - object->setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true); - object->parameterChanged(LLNetworkData::PARAMS_FLEXIBLE, true); - } - else - { - // send param not in use in case the supply prim has it - object->setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, true); - object->parameterChanged(LLNetworkData::PARAMS_FLEXIBLE, true); - } - if (from->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) - { - LLLightParams light = *((LLLightParams*)from->getParameterEntry(LLNetworkData::PARAMS_LIGHT)); - object->setParameterEntry(LLNetworkData::PARAMS_LIGHT, light, true); - object->setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true); - object->parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - else - { - // send param not in use in case the supply prim has it - object->setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, FALSE, true); - object->parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - 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); - } - else - { - // send param not in use in case the supply prim has it - object->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, true); - object->parameterChanged(LLNetworkData::PARAMS_SCULPT, true); - } - // Textures - U8 te_count = from->getNumTEs(); - for (U8 i = 0; i < te_count; i++) - { - 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(); - // Flag update is already coming from somewhere - //object->updateFlags(); - - // Transforms - object->setScale(from->getScale(), FALSE); - object->setRotation(from->getRotation(), FALSE); - object->setPosition(from->getPosition(), FALSE); - - U8 data[256]; - S32 offset = 0; - // Position and rotation - gMessageSystem->newMessageFast(_PREHASH_MultipleObjectUpdate); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); - gMessageSystem->addU8Fast(_PREHASH_Type, 3); - htonmemcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12); - offset += 12; - LLQuaternion quat = object->getRotation(); - LLVector3 vec = quat.packToVector3(); - htonmemcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12); - offset += 12; - gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - // Position and scale - offset = 0; - gMessageSystem->newMessageFast(_PREHASH_MultipleObjectUpdate); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); - gMessageSystem->addU8Fast(_PREHASH_Type, 5); - htonmemcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12); - offset += 12; - htonmemcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12); - offset += 12; - gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - - // Name - if(from->mPrimName != "") - { - gMessageSystem->newMessageFast(_PREHASH_ObjectName); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_LocalID, object->getLocalID()); - gMessageSystem->addStringFast(_PREHASH_Name, from->mPrimName); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - } - - if(currPrimIndex + 1 >= (int)sPrims.size()) - { - // Link time - int packet_len = 0; - for(std::map >::iterator itr = sLinkSets.begin();itr != sLinkSets.end();++itr) - { - std::queue linkset = (*itr).second; - gMessageSystem->newMessageFast(_PREHASH_ObjectLink); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*itr).first);//this is the parent prim - while(!linkset.empty()) - { - if(packet_len == 254) //if we have 255 objects, using 254 because root counts as 1 too - { - gMessageSystem->sendReliable(gAgent.getRegionHost()); - packet_len = 0; - gMessageSystem->newMessageFast(_PREHASH_ObjectLink); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*itr).first);//this is the parent prim - } - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, linkset.front()); - linkset.pop(); - packet_len++; - } - if(packet_len) //send if it hasnt been yet - { - gMessageSystem->sendReliable(gAgent.getRegionHost()); - packet_len = 0; - } - } - - // stop the throttle - F32 throttle = gSavedSettings.getF32("OutBandwidth"); - if(throttle != 0.) - { - gMessageSystem->mPacketRing.setOutBandwidth(throttle); - gMessageSystem->mPacketRing.setUseOutThrottle(TRUE); - } - else - { - gMessageSystem->mPacketRing.setOutBandwidth(0.0); - gMessageSystem->mPacketRing.setUseOutThrottle(FALSE); - } - - if(sId2attachpt.size() == 0) - { - sImportInProgress = false; - std::string msg = "Imported " + sXmlImportOptions->mName; - LLChat chat(msg); - LLFloaterChat::addChat(chat); - LLFloaterImportProgress::update(); - return; - } - else - { - // Take attachables into inventory - std::string msg = "Wait a few moments for the attachments to link and attach..."; - LLChat chat(msg); - LLFloaterChat::addChat(chat); - U32 ip = gAgent.getRegionHost().getAddress(); - U32 port = gAgent.getRegionHost().getPort(); - std::vector roots; - roots.resize(sLinkSets.size()); - for(std::map >::iterator itr = sLinkSets.begin();itr != sLinkSets.end();++itr) - { - LLUUID id = LLUUID::null; - LLViewerObjectList::getUUIDFromLocal(id,itr->first,ip,port); - if(id.notNull()) - { - roots.push_back(id); - } - } - sAttachmentsDone = 0; - new LLLinkTimer(roots); - } - } - LLFloaterImportProgress::update(); - rez_supply(); -} -void LLXmlImport::finish_link() -{ - std::map::iterator at_iter = sId2attachpt.begin(); - std::map::iterator at_end = sId2attachpt.end(); - for( ; at_iter != at_end; ++at_iter) - { - LLUUID tid; - tid.generate(); - U32 at_localid = sId2localid[(*at_iter).first]; - gMessageSystem->newMessageFast(_PREHASH_DeRezObject); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_AgentBlock); - gMessageSystem->addUUIDFast(_PREHASH_GroupID, LLUUID::null); - gMessageSystem->addU8Fast(_PREHASH_Destination, DRD_TAKE_INTO_AGENT_INVENTORY); - gMessageSystem->addUUIDFast(_PREHASH_DestinationID, sFolderID); - gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid); - gMessageSystem->addU8Fast(_PREHASH_PacketCount, 1); - gMessageSystem->addU8Fast(_PREHASH_PacketNumber, 0); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, at_localid); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - } -} -// static -void LLXmlImport::onNewItem(LLViewerInventoryItem* item) -{ - U8 attachpt = sId2attachpt[item->getDescription()]; - if(attachpt) - { - // clear description, part 1 - item->setDescription(std::string("(No Description)")); - item->updateServer(FALSE); - - // Attach it - gMessageSystem->newMessageFast(_PREHASH_RezSingleAttachmentFromInv); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getUUID()); - gMessageSystem->addUUIDFast(_PREHASH_OwnerID, gAgent.getID()); - gMessageSystem->addU8Fast(_PREHASH_AttachmentPt, attachpt); - gMessageSystem->addU32Fast(_PREHASH_ItemFlags, 0); - gMessageSystem->addU32Fast(_PREHASH_GroupMask, 0); - gMessageSystem->addU32Fast(_PREHASH_EveryoneMask, 0); - gMessageSystem->addU32Fast(_PREHASH_NextOwnerMask, 0); - gMessageSystem->addStringFast(_PREHASH_Name, item->getName()); - gMessageSystem->addStringFast(_PREHASH_Description, ""); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - } -} - -// static -void LLXmlImport::onNewAttachment(LLViewerObject* object) -{ - if(sPt2attachpos.size() == 0) return; - - U8 attachpt = (U8)object->getAttachmentPoint(); - if(sPt2watch[attachpt]) - { - // clear description, part 2 - gMessageSystem->newMessageFast(_PREHASH_ObjectDescription); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_LocalID, object->getLocalID()); - gMessageSystem->addStringFast(_PREHASH_Description, ""); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - - // position and rotation - LLVector3 pos = sPt2attachpos[attachpt]; - U8 data[256]; - S32 offset = 0; - gMessageSystem->newMessageFast(_PREHASH_MultipleObjectUpdate); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); - gMessageSystem->addU8Fast(_PREHASH_Type, 11); // link set this time - htonmemcpy(&data[offset], &(pos.mV), MVT_LLVector3, 12); - offset += 12; - LLQuaternion quat = sPt2attachrot[attachpt]; - LLVector3 vec = quat.packToVector3(); - htonmemcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12); - offset += 12; - gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - - // Select and deselect to make it send an update - gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - - gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); - gMessageSystem->sendReliable(gAgent.getRegionHost()); - - // Done? - sAttachmentsDone++; - if(sAttachmentsDone >= (int)sPt2attachpos.size()) - { - sImportInProgress = false; - std::string msg = "Imported " + sXmlImportOptions->mName; - LLChat chat(msg); - LLFloaterChat::addChat(chat); - LLFloaterImportProgress::update(); - return; - } - } -} - - - -// static -void LLXmlImport::Cancel(void* user_data) -{ - sImportInProgress = false; - LLFloaterImportProgress::sInstance->close(false); -} - -// - diff --git a/indra/newview/llimportobject.h b/indra/newview/llimportobject.h deleted file mode 100644 index 77d3bfe33..000000000 --- a/indra/newview/llimportobject.h +++ /dev/null @@ -1,120 +0,0 @@ -// -/** - * @file llimportobject.h - */ - -#ifndef LL_LLIMPORTOBJECT_H -#define LL_LLIMPORTOBJECT_H - -#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 -{ -public: - std::string mName; - int mType; - std::string mData; - LLSD mOrginalLLSD; - LLImportWearable(LLSD sd); - std::list mTextures; - void replaceTextures(std::map textures_replace); -}; - -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; - bool importIsAttachment; - U32 importAttachPoint; - LLVector3 importAttachPos; - LLQuaternion importAttachRot; - std::list mTextures; -}; - -class LLXmlImportOptions -{ - friend bool operator==(const LLXmlImportOptions &a, const LLXmlImportOptions &b); - friend bool operator!=(const LLXmlImportOptions &a, const LLXmlImportOptions &b); -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 mAssets; - std::vector mRootObjects; - std::vector mChildObjects; - std::vector mWearables; - BOOL mKeepPosition; - LLViewerObject* mSupplier; - BOOL mReplaceTexture; -protected: - LLUUID mID; -}; - - -class LLXmlImport -{ -public: - static void import(LLXmlImportOptions* import_options); - static void onNewPrim(LLViewerObject* object); - static void onNewItem(LLViewerInventoryItem* item); - static void onNewAttachment(LLViewerObject* object); - static void Cancel(void* user_data); - static void rez_supply(); - static void finish_init(); - static void finish_link(); - - static bool sImportInProgress; - static bool sImportHasAttachments; - static LLUUID sFolderID; - static LLViewerObject* sSupplyParams; - static int sPrimsNeeded; - static std::vector sPrims; // all prims being imported - static std::map sPt2watch; // attach points that need watching - static std::map sId2attachpt; // attach points of all attachables - static std::map sPt2attachpos; // positions of all attachables - static std::map sPt2attachrot; // rotations of all attachables - static std::map > sLinkSets;//Linksets to link. - static int sPrimIndex; - static int sAttachmentsDone; - static std::map sId2localid; - static std::map sRootpositions; - static std::map sRootrotations; - static LLXmlImportOptions* sXmlImportOptions; - - static int sTotalAssets; - static int sUploadedAssets; - static std::map sTextureReplace; -}; - -#endif -// - diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index fe105e24b..176d26e44 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -96,7 +96,6 @@ #include "llappviewer.h" // System Folders #include "llfloateranimpreview.h" // for reuploads #include "llfloaterimagepreview.h" // for reuploads -#include "llimportobject.h" // for disabling options during import //#include "llcheats.h" #include "dofloaterhex.h" #include "hgfloatertexteditor.h" @@ -2397,17 +2396,10 @@ void LLFolderBridge::folderOptionsMenu() // Only enable add/replace outfit for non-default folders. if (!is_default_folder) { - // don't allow attaching stuff during attachment import - if(!(LLXmlImport::sImportInProgress && LLXmlImport::sImportHasAttachments)) - { - // - if (gHippoGridManager->getConnectedGrid()->supportsInvLinks()) - mItems.push_back(std::string("Add To Outfit")); - mItems.push_back(std::string("Wear Items")); - mItems.push_back(std::string("Replace Outfit")); - // - } - // + if (gHippoGridManager->getConnectedGrid()->supportsInvLinks()) + mItems.push_back(std::string("Add To Outfit")); + mItems.push_back(std::string("Wear Items")); + mItems.push_back(std::string("Replace Outfit")); } mItems.push_back(std::string("Take Off Items")); } @@ -4172,10 +4164,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else // - // don't allow attaching objects while importing attachments - //if( !isInTrash() ) - if( !isInTrash() && !(LLXmlImport::sImportInProgress && LLXmlImport::sImportHasAttachments)) - // + if( !isInTrash() ) { items.push_back(std::string("Attach Separator")); items.push_back(std::string("Object Wear")); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 6e16c24a3..eeae559e2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -60,7 +60,6 @@ #include "llvoavatar.h" #include "llsdutil.h" // -#include "llimportobject.h" #include "llappviewer.h" // gLostItemsRoot // #include @@ -1977,10 +1976,6 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) if(item) { mItemMap[item->getUUID()] = item; - // - if(LLXmlImport::sImportInProgress) - LLXmlImport::onNewItem(item); - // } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 8a6a41ff7..0478df637 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -93,10 +93,6 @@ #include "rlvhandler.h" // [/RLVa:KB] -// -#include "llfloaterexport.h" -// - #include "llglheaders.h" LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; @@ -4400,10 +4396,6 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data } } - // Send to export floaters - LLFloaterExport::receiveObjectProperties(id, name, desc); - // - // Iterate through nodes at end, since it can be on both the regular AND hover list struct f : public LLSelectedNodeFunctor { @@ -4537,7 +4529,7 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use if(sObjectPropertiesFamilyRequests.count(id) != 0 ) { // Send to export floaters - LLFloaterExport::receiveObjectProperties(id, name, desc); + //LLFloaterExport::receiveObjectProperties(id, name, desc); // We got the reply, so remove the object from the list of pending requests sObjectPropertiesFamilyRequests.erase(id); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 34ca31e78..afcbf7cbf 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -62,8 +62,6 @@ #include "llsdutil.h" // #include "lllocalinventory.h" -#include "llfloaterimport.h" -#include "llfloaterexport.h" #include "llfloaterexploreanimations.h" #include "llfloaterexploresounds.h" #include "llfloaterblacklist.h" @@ -113,7 +111,6 @@ #include "llfloatercustomize.h" #include "llfloaterdaycycle.h" //#include "llfloaterdickdongs.h" No need for the custom floater right now, I think. -HgB -#include "ascentuploadbrowser.h" //New customer floater attempts #include "llfloaterdirectory.h" #include "llfloatereditui.h" #include "llfloaterchatterbox.h" @@ -253,6 +250,7 @@ #include "llavatarnamecache.h" #include "floaterao.h" #include "slfloatermediafilter.h" +#include "llviewerobjectbackup.h" #include "hippogridmanager.h" @@ -578,14 +576,6 @@ void handle_grab_texture(void*); BOOL enable_grab_texture(void*); void handle_dump_region_object_cache(void*); - - - - - - - - BOOL menu_ui_enabled(void *user_data); BOOL menu_check_control( void* user_data); void menu_toggle_variable( void* user_data ); @@ -2538,64 +2528,6 @@ class LLObjectCopyUUID : public view_listener_t } }; -class LLObjectEnableImport : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - bool new_value = (object != NULL); - if(object) - { - if(!object->permCopy()) - new_value = false; - else if(!object->permModify()) - new_value = false; - else if(!object->permMove()) - new_value = false; - else if(object->numChildren() != 0) - new_value = false; - else if(object->getParent()) - new_value = false; - } - gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); - return true; - } -}; - -class LLObjectImport : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - bool new_value = (object != NULL); - if(object) - { - if(!object->permCopy()) - new_value = false; - else if(!object->permModify()) - new_value = false; - else if(!object->permMove()) - new_value = false; - else if(object->numChildren() != 0) - new_value = false; - else if(object->getParent()) - new_value = false; - } - if(new_value == false) return true; - - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(LLFilePicker::FFLOAD_XML)) - { - return true; - } - std::string file_name = picker.getFirstFile(); - LLXmlImportOptions* options = new LLXmlImportOptions(file_name); - options->mSupplier = object; - new LLFloaterXmlImportOptions(options); - return true; - } -}; - class LLObjectData : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -2864,6 +2796,90 @@ class LLGoToObject : public view_listener_t } }; +//--------------------------------------------------------------------------- +// Object backup +//--------------------------------------------------------------------------- + +class LLObjectEnableExport : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + bool new_value = (object != NULL); + if (new_value) + { + struct ff : public LLSelectedNodeFunctor + { + ff(const LLSD& data) : LLSelectedNodeFunctor(), userdata(data) + { + } + const LLSD& userdata; + virtual bool apply(LLSelectNode* node) + { + // Note: the actual permission checking algorithm depends on the grid TOS and must be + // performed for each prim and texture. This is done later in llviewerobjectbackup.cpp. + // This means that even if the item is enabled in the menu, the export may fail should + // the permissions not be met for each exported asset. The permissions check below + // therefore only corresponds to the minimal permissions requirement common to all grids. + LLPermissions *item_permissions = node->mPermissions; + return (gAgent.getID() == item_permissions->getOwner() && + (gAgent.getID() == item_permissions->getCreator() || + (item_permissions->getMaskOwner() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)); + } + }; + ff * the_ff = new ff(userdata); + new_value = LLSelectMgr::getInstance()->getSelection()->applyToNodes(the_ff, false); + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLObjectExport : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return true; + + LLVOAvatar* avatar = find_avatar_from_object(object); + + if (!avatar) + { + LLObjectBackup::getInstance()->exportObject(); + } + + return true; + } +}; + +class LLObjectEnableImport : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + gMenuHolder->findControl(userdata["control"].asString())->setValue(TRUE); + return true; + } +}; + +class LLObjectImport : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLObjectBackup::getInstance()->importObject(FALSE); + return true; + } +}; + +class LLObjectImportUpload : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLObjectBackup::getInstance()->importObject(TRUE); + return true; + } +}; + //--------------------------------------------------------------------------- // Parcel freeze, eject, etc. //--------------------------------------------------------------------------- @@ -6597,10 +6613,6 @@ class LLShowFloater : public view_listener_t { LLFloaterPerms::toggleInstance(LLSD()); } - else if (floater_name == "ascentuploadbrowser") - { - ASFloaterUploadBrowser::show(NULL); - } return true; } }; @@ -7420,10 +7432,6 @@ class LLObjectEnableWear : public view_listener_t bool handleEvent(LLPointer event, const LLSD& userdata) { bool is_wearable = object_selected_and_point_valid(NULL); - // Don't allow attaching objects while importing attachments - if(LLXmlImport::sImportInProgress && LLXmlImport::sImportHasAttachments) - is_wearable = false; - // gMenuHolder->findControl(userdata["control"].asString())->setValue(is_wearable); return TRUE; } @@ -10323,22 +10331,6 @@ void initialize_menus() addMenu(new LLViewCheckRenderType(), "View.CheckRenderType"); addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); - - - - - - - - - - - - - - - - // World menu addMenu(new LLWorldChat(), "World.Chat"); addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun"); @@ -10452,7 +10444,6 @@ void initialize_menus() addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse"); addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse"); // - addMenu(new LLObjectImport(), "Object.Import"); addMenu(new LLObjectMeasure(), "Object.Measure"); addMenu(new LLObjectData(), "Object.Data"); addMenu(new LLScriptCount(), "Object.ScriptCount"); @@ -10467,6 +10458,10 @@ void initialize_menus() addMenu(new LLObjectInspect(), "Object.Inspect"); // Visual mute, originally by Phox. addMenu(new LLObjectDerender(), "Object.DERENDER"); + addMenu(new LLObjectExport(), "Object.Export"); + addMenu(new LLObjectImport(), "Object.Import"); + addMenu(new LLObjectImportUpload(), "Object.ImportUpload"); + addMenu(new LLObjectEnableOpen(), "Object.EnableOpen"); addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); @@ -10475,11 +10470,10 @@ void initialize_menus() addMenu(new LLObjectEnableWear(), "Object.EnableWear"); addMenu(new LLObjectEnableReturn(), "Object.EnableReturn"); addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); - // - addMenu(new LLObjectEnableImport(), "Object.EnableImport"); - // addMenu(new LLObjectEnableMute(), "Object.EnableMute"); addMenu(new LLObjectEnableBuy(), "Object.EnableBuy"); + addMenu(new LLObjectEnableExport(), "Object.EnableExport"); + addMenu(new LLObjectEnableImport(), "Object.EnableImport"); /*addMenu(new LLObjectVisibleTouch(), "Object.VisibleTouch"); addMenu(new LLObjectVisibleCustomTouch(), "Object.VisibleCustomTouch"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index a706b02ab..8fa19c504 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -65,8 +65,6 @@ #include "lluploaddialog.h" // #include "llselectmgr.h" -#include "llfloaterimport.h" -#include "llfloaterexport.h" #include "llassettype.h" #include "llinventorytype.h" #include "llbvhloader.h" @@ -432,35 +430,6 @@ class LLFileUploadBulk : public view_listener_t } }; -// -class LLFileImportXML : public view_listener_t -{ - bool handleEvent(LLPointer 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 event, const LLSD& userdata) - { - bool new_value = !LLXmlImport::sImportInProgress; - - // horrendously opaque, this code - gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); - return true; - } -}; -// - void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args) { llwarns << error_message << llendl; @@ -533,20 +502,8 @@ class LLFileSaveTexture : public view_listener_t LLFloater* top = gFloaterView->getFrontmost(); if (top) { - // - if(top->canSaveAs()) - { - // - top->saveAs(); - // - return true; - } - // + top->saveAs(); } - // - top = new LLFloaterExport(); - top->center(); - // return true; } }; @@ -1348,10 +1305,6 @@ void init_menu_file() (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound"); (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim"); (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk"); - // - (new LLFileImportXML())->registerListener(gMenuHolder, "File.ImportXML"); - (new LLFileEnableImportXML())->registerListener(gMenuHolder, "File.EnableImportXML"); - // (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow"); (new LLFileCloseAllWindows())->registerListener(gMenuHolder, "File.CloseAllWindows"); (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow"); diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp new file mode 100755 index 000000000..8892de13f --- /dev/null +++ b/indra/newview/llviewerobjectbackup.cpp @@ -0,0 +1,1197 @@ +/** + * @file llviewerobjectbackup.cpp + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +// system library includes +#include +#include +#include + +#include "hippogridmanager.h" + +// linden library includes +#include "indra_constants.h" +#include "llapr.h" +#include "llalertdialog.h" +#include "llcallbacklist.h" +#include "lldir.h" +#include "lleconomy.h" +#include "llhttpclient.h" +#include "llimage.h" +#include "llimagej2c.h" +#include "lllfsthread.h" +#include "llsdserialize.h" +#include "llsdutil.h" +#include "llsdutil_math.h" +#include "lltransactiontypes.h" + +// newview includes +#include "llagent.h" +#include "llappviewer.h" +#include "llassetuploadresponders.h" +#include "llfilepicker.h" +#include "llfloateranimpreview.h" +#include "llfloaterbuycurrency.h" +#include "llfloaterimagepreview.h" +#include "llfloaternamedesc.h" +#include "llfloatersnapshot.h" +#include "llinventorymodel.h" // gInventory +#include "llnotify.h" +#include "llresourcedata.h" +#include "llselectmgr.h" +#include "llstatusbar.h" +#include "lltexturecache.h" +#include "lltoolplacer.h" +#include "lluictrlfactory.h" +#include "lluploaddialog.h" +#include "llviewercontrol.h" +#include "llviewerimagelist.h" +#include "llviewerobjectlist.h" +#include "llviewermenu.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "llviewerwindow.h" + +#include "llviewerobjectbackup.h" + +LLObjectBackup* LLObjectBackup::sInstance = 0; + +class importResponder: public LLNewAgentInventoryResponder +{ +public: + + importResponder(const LLSD& post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type) + : LLNewAgentInventoryResponder(post_data, vfile_id, asset_type) + { + } + + //virtual + virtual void uploadComplete(const LLSD& content) + { + lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; + + LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); + LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); + + // Update L$ and ownership credit information + // since it probably changed on the server + if (asset_type == LLAssetType::AT_TEXTURE || + asset_type == LLAssetType::AT_SOUND || + asset_type == LLAssetType::AT_ANIMATION) + { + gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_MoneyData); + gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); + gAgent.sendReliableMessage(); + +// LLStringUtil::format_map_t args; +// args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); +// LLNotifyBox::showXml("UploadPayment", args); + } + + // Actually add the upload to viewer inventory + llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " + << content["new_asset"].asUUID() << " to inventory." << llendl; + if (mPostData["folder_id"].asUUID().notNull()) + { + LLPermissions perm; + U32 next_owner_perm; + perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + if (mPostData["inventory_type"].asString() == "snapshot") + { + next_owner_perm = PERM_ALL; + } + else + { + next_owner_perm = PERM_MOVE | PERM_TRANSFER; + } + perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); + S32 creation_date_now = time_corrected(); + LLPointer item + = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), + mPostData["folder_id"].asUUID(), + perm, + content["new_asset"].asUUID(), + asset_type, + inventory_type, + mPostData["name"].asString(), + mPostData["description"].asString(), + LLSaleInfo::DEFAULT, + LLInventoryItem::II_FLAGS_NONE, + creation_date_now); + gInventory.updateItem(item); + gInventory.notifyObservers(); + } + else + { + llwarns << "Can't find a folder to put it into" << llendl; + } + + // remove the "Uploading..." message + LLUploadDialog::modalUploadFinished(); + + LLObjectBackup::getInstance()->updateMap(content["new_asset"].asUUID()); + LLObjectBackup::getInstance()->uploadNextAsset(); + } +}; + +class CacheReadResponder : public LLTextureCache::ReadResponder +{ +public: + CacheReadResponder(const LLUUID& id, LLImageFormatted* image) + : mFormattedImage(image), mID(id) + { + setImage(image); + } + void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) + { + if (imageformat == IMG_CODEC_TGA && mFormattedImage->getCodec() == IMG_CODEC_J2C) + { + llwarns << "FAILED: texture " << mID << " is formatted as TGA. Not saving." << llendl; + LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_BAD_ENCODING; + 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; + std::string name; + mID.toString(name); + name = LLObjectBackup::getInstance()->getfolder() + "//" + name; + llinfos << "Saving to " << name << llendl; + if (!mFormattedImage->save(name)) + { + llwarns << "FAILED to save texture " << mID << llendl; + LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_SAVED_FAILED; + } + } + else + { + if (!success) + { + llwarns << "FAILED to get texture " << mID << llendl; + LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_MISSING; + } + if (mFormattedImage.isNull()) + { + llwarns << "FAILED: NULL texture " << mID << llendl; + LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_IS_NULL; + } + } + + LLObjectBackup::getInstance()->mNextTextureReady = true; + //JUST SAY NO TO APR DEADLOCKING + //LLObjectBackup::getInstance()->exportNextTexture(); + } +private: + LLPointer mFormattedImage; + LLUUID mID; +}; + +LLObjectBackup::LLObjectBackup() +: LLFloater(std::string("Object Backup Floater"), std::string("FloaterObjectBackuptRect"), LLStringUtil::null) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_object_backup.xml"); + mRunning = false; + mTexturesList.clear(); + mAssetMap.clear(); + mCurrentAsset = LLUUID::null; + mRetexture = false; + close(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLObjectBackup* LLObjectBackup::getInstance() +{ + if (!sInstance) + sInstance = new LLObjectBackup(); + return sInstance; +} + +LLObjectBackup::~LLObjectBackup() +{ + // save position of floater + gSavedSettings.setRect("FloaterObjectBackuptRect", getRect()); + sInstance = NULL; +} + +void LLObjectBackup::draw() +{ + LLFloater::draw(); +} + +void LLObjectBackup::show(bool exporting) +{ + // set the title + if (exporting) + { + setTitle("Object export"); + } + else + { + setTitle("Object import"); + } + mCurObject = 1; + mCurPrim = 0; + mObjects = 0; + mPrims = 0; + mRezCount = 0; + + // make floater appear + setVisibleAndFrontmost(); +} + +void LLObjectBackup::onClose(bool app_quitting) +{ + setVisible(false); + // HACK for fast XML iteration replace with: + // destroy(); +} + +void LLObjectBackup::updateExportNumbers() +{ + std::stringstream sstr; + LLUICtrl* ctrl = getChild("name_label"); + + sstr << "Export Progress \n"; + + sstr << "Remaining Textures " << mTexturesList.size() << "\n"; + ctrl->setValue(LLSD("Text") = sstr.str()); +} + +void LLObjectBackup::updateImportNumbers() +{ + std::stringstream sstr; + LLUICtrl* ctrl = getChild("name_label"); + + if (mRetexture) + { + sstr << " Textures uploads remaining : " << mTexturesList.size() << "\n"; + ctrl->setValue(LLSD("Text") = sstr.str()); + } + else + { + sstr << " Textures uploads N/A \n"; + ctrl->setValue(LLSD("Text") = sstr.str()); + } + + sstr << " Objects " << mCurObject << "/" << mObjects << "\n"; + ctrl->setValue(LLSD("Text") = sstr.str()); + + sstr << " Rez "<< mRezCount << "/" << mPrims; + ctrl->setValue(LLSD("Text") = sstr.str()); + + sstr << " Build " << mCurPrim << "/" << mPrims; + ctrl->setValue(LLSD("Text") = sstr.str()); +} + +void LLObjectBackup::exportObject() +{ + mTexturesList.clear(); + mLLSD.clear(); + mThisGroup.clear(); + + // Open the file save dialog + LLFilePicker& file_picker = LLFilePicker::instance(); + if (!file_picker.getSaveFile(LLFilePicker::FFSAVE_XML)) + { + // User canceled save. + return; + } + + mFileName = file_picker.getCurFile(); + mFolder = gDirUtilp->getDirName(mFileName); + + mNonExportedTextures = TEXTURE_OK; + + mExportState = EXPORT_INIT; + gIdleCallbacks.addFunction(exportWorker, NULL); +} + +bool LLObjectBackup::validatePerms(const LLPermissions *item_permissions) +{ + if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_SECONDLIFE) + { + // In Second Life, you must be the creator to be permitted to export the asset. + return (gAgent.getID() == item_permissions->getOwner() && + gAgent.getID() == item_permissions->getCreator()); + } + else + { + // Out of Second Life, simply check that the asset is full perms. + return (gAgent.getID() == item_permissions->getOwner() && + (item_permissions->getMaskOwner() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); + } +} + +// So far, only Second Life forces TPVs to verify the creator for textures... +// which sucks, because there is no other way to check for the texture +// permissions or creator than to try and find the asset(s) corresponding to +// the texture in the inventory and check the permissions/creator on the said +// asset(s), meaning that if you created the texture and subsequently deleted +// it from your inventory, you will not be able to export it any more !!! +// The "must be creator" stuff also goes against the usage in Linden Lab's own +// official viewers, since those allow you to save full perm textures (such as +// the textures in the Library), whoever is the actual creator... Go figure ! +LLUUID LLObjectBackup::validateTextureID(LLUUID asset_id) +{ + if (gHippoGridManager->getConnectedGrid()->getPlatform() != HippoGridInfo::PLATFORM_SECONDLIFE) + { + // If we are not in Second Life, don't bother. + return asset_id; + } + LLUUID texture = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(asset_id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + if (items.count()) + { + for (S32 i = 0; i < items.count(); i++) + { + const LLPermissions item_permissions = items[i]->getPermissions(); + if (validatePerms(&item_permissions)) + { + texture = asset_id; + } + } + } + + if (texture != asset_id) + { + mNonExportedTextures |= TEXTURE_BAD_PERM; + } + + return texture; +} + +void LLObjectBackup::exportWorker(void *userdata) +{ + LLObjectBackup::getInstance()->updateExportNumbers(); + + switch (LLObjectBackup::getInstance()->mExportState) + { + case EXPORT_INIT: + { + LLObjectBackup::getInstance()->show(true); + LLSelectMgr::getInstance()->getSelection()->ref(); + struct ff : public LLSelectedNodeFunctor + { + virtual bool apply(LLSelectNode* node) + { + return LLObjectBackup::getInstance()->validatePerms(node->mPermissions); + } + } func; + + if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) + { + LLObjectBackup::getInstance()->mExportState = EXPORT_STRUCTURE; + } + else + { + llwarns << "Incorrect permission to export" << llendl; + LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED; + LLSelectMgr::getInstance()->getSelection()->unref(); + } + } + break; + + case EXPORT_STRUCTURE: + { + struct ff : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + object->boostTexturePriority(TRUE); + LLViewerObject::child_list_t children = object->getChildren(); + children.push_front(object); //push root onto list + LLSD prim_llsd = LLObjectBackup::getInstance()->primsToLLSD(children); + LLSD stuff; + stuff["root_position"] = object->getPosition().getValue(); + stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); + stuff["group_body"] = prim_llsd; + LLObjectBackup::getInstance()->mLLSD["data"].append(stuff); + return true; + } + } func; + + LLObjectBackup::getInstance()->mExportState = EXPORT_LLSD; + LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); + LLSelectMgr::getInstance()->getSelection()->unref(); + } + break; + + case EXPORT_TEXTURES: + if (LLObjectBackup::getInstance()->mNextTextureReady == false) + return; + + // Ok we got work to do + LLObjectBackup::getInstance()->mNextTextureReady = false; + + if (LLObjectBackup::getInstance()->mTexturesList.empty()) + { + LLObjectBackup::getInstance()->mExportState = EXPORT_DONE; + return; + } + + LLObjectBackup::getInstance()->exportNextTexture(); + break; + + case EXPORT_LLSD: + { + // Create a file stream and write to it + llofstream export_file(LLObjectBackup::getInstance()->mFileName); + LLSDSerialize::toPrettyXML(LLObjectBackup::getInstance()->mLLSD, export_file); + export_file.close(); + LLObjectBackup::getInstance()->mNextTextureReady = true; + LLObjectBackup::getInstance()->mExportState = EXPORT_TEXTURES; + } + break; + + case EXPORT_DONE: + gIdleCallbacks.deleteFunction(exportWorker); + if (LLObjectBackup::getInstance()->mNonExportedTextures == LLObjectBackup::TEXTURE_OK) + { + llinfos << "Export successful and complete." << llendl; + LLNotifications::instance().add("ExportSuccessful"); + } + else + { + llinfos << "Export successful but incomplete: some texture(s) not saved." << llendl; + std::string reason; + if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_PERM) + { + reason += "\nBad permissions/creator."; + } + if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_MISSING) + { + reason += "\nMissing texture."; + } + if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_ENCODING) + { + reason += "\nBad texture encoding."; + } + if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_IS_NULL) + { + reason += "\nNull texture."; + } + if (LLObjectBackup::getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_SAVED_FAILED) + { + reason += "\nCould not write to disk."; + } + LLSD args; + args["REASON"] = reason; + LLNotifications::instance().add("ExportPartial", args); + } + LLObjectBackup::getInstance()->close(); + break; + + case EXPORT_FAILED: + gIdleCallbacks.deleteFunction(exportWorker); + llwarns << "Export process aborted." << llendl; + LLNotifications::instance().add("ExportFailed"); + LLObjectBackup::getInstance()->close(); + break; + } +} + +LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list) +{ + LLViewerObject* object; + LLSD llsd; + char localid[16]; + + for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) + { + object = (*i); + LLUUID id = object->getID(); + + llinfos << "Exporting prim " << object->getID().asString() << llendl; + + // Create an LLSD object that represents this prim. It will be injected in to the overall LLSD + // tree structure + LLSD prim_llsd; + + if (!object->isRoot()) + { + // Parent id + snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID()); + prim_llsd["parent"] = localid; + } + + // Name and description + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(object); + if (node) + { + prim_llsd["name"] = node->mName; + prim_llsd["description"] = node->mDescription; + } + + // 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 paramsb6fab961-af18-77f8-cf08-f021377a7244 + 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(); + + LLUUID sculpt_texture = sculpt->getSculptTexture(); + if (sculpt_texture == validateTextureID(sculpt_texture)) + { + bool alreadyseen = false; + std::list::iterator iter; + for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) + { + if ((*iter) == sculpt_texture) + alreadyseen = true; + } + if (alreadyseen == false) + { + llinfos << "Found a sculpt texture, adding to list " << sculpt_texture << llendl; + mTexturesList.push_back(sculpt_texture); + } + } + else + { + llwarns << "Incorrect permission to export a sculpt texture." << llendl; + LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED; + } + } + + // Textures + LLSD te_llsd; + LLSD this_te_llsd; + LLUUID t_id; + U8 te_count = object->getNumTEs(); + for (U8 i = 0; i < te_count; i++) + { + bool alreadyseen = false; + t_id = validateTextureID(object->getTE(i)->getID()); + this_te_llsd = object->getTE(i)->asLLSD(); + this_te_llsd["imageid"] = t_id; + te_llsd.append(this_te_llsd); + std::list::iterator iter; + for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) + { + if ((*iter) == t_id) + alreadyseen = true; + } + if (alreadyseen == false) + mTexturesList.push_back(t_id); + } + prim_llsd["textures"] = te_llsd; + + // The keys in the primitive maps do not have to be localids, they can be any + // string. We simply use localids because they are a unique identifier + snprintf(localid, sizeof(localid), "%u", object->getLocalID()); + llsd[(const char*)localid] = prim_llsd; + } + updateExportNumbers(); + return llsd; +} + +void LLObjectBackup::exportNextTexture() +{ + if (mTexturesList.empty()) + { + llinfos << "Finished exporting textures." << llendl; + return; + } + + LLUUID id; + std::list::iterator iter; + iter = mTexturesList.begin(); + + while (1) + { + if (iter == mTexturesList.end()) + { + mNextTextureReady = true; + return; + } + + id = (*iter); + + LLViewerImage* imagep = gImageList.hasImage(id); + if (imagep != NULL) + { + S32 cur_discard = imagep->getDiscardLevel(); + if (cur_discard > 0) + { + if (imagep->getBoostLevel() != LLViewerImageBoostLevel::BOOST_PREVIEW) + { + // we want to force discard 0: this one does this. + imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); + } + } + else + { + break; + } + } + else + { + llwarns << "We *DON'T* have the texture " << llendl; + mNonExportedTextures |= TEXTURE_MISSING; + } + iter++; + } + + mTexturesList.remove(id); + + llinfos << "Requesting texture " << id << llendl; + LLImageJ2C* mFormattedImage = new LLImageJ2C; + CacheReadResponder* responder = new CacheReadResponder(id, mFormattedImage); + LLAppViewer::getTextureCache()->readFromCache(id, LLWorkerThread::PRIORITY_HIGH, 0, 999999, responder); +} + +void LLObjectBackup::importObject(bool upload) +{ + mTexturesList.clear(); + mAssetMap.clear(); + mCurrentAsset = LLUUID::null; + + mRetexture = upload; + + // Open the file open dialog + LLFilePicker& file_picker = LLFilePicker::instance(); + if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_XML)) + { + // User canceled save. + return; + } + + std::string file_name = file_picker.getFirstFile().c_str(); + mFolder = gDirUtilp->getDirName(file_name); + llifstream import_file(file_name); + LLSDSerialize::fromXML(mLLSD, import_file); + import_file.close(); + + mAgentPos = gAgent.getPositionAgent(); + mAgentRot = LLQuaternion(gAgent.getAtAxis(), gAgent.getLeftAxis(), gAgent.getUpAxis()); + + // Get the texture map + + LLSD::map_const_iterator prim_it; + LLSD::array_const_iterator prim_arr_it; + + mCurObject = 1; + mCurPrim = 1; + mObjects = mLLSD["data"].size(); + mPrims = 0; + mRezCount = 0; + + if (mObjects <= 0) { + LLSD args; + args["MESSAGE"] = std::string("Object import failed.\nThe XML file has an incompatble format or does not contain any objects."); + LLNotifications::instance().add("GenericAlert", args); + llwarns << "Trying to import illegal XML object file." << llendl; + return; + } + + show(false); + + updateImportNumbers(); + + for (prim_arr_it = mLLSD["data"].beginArray(); prim_arr_it != mLLSD["data"].endArray(); prim_arr_it++) + { + LLSD llsd2 = (*prim_arr_it)["group_body"]; + + for (prim_it = llsd2.beginMap(); prim_it != llsd2.endMap(); prim_it++) + { + LLSD prim_llsd = llsd2[prim_it->first]; + LLSD::array_iterator text_it; + std::list::iterator iter; + + if (prim_llsd.has("sculpt")) + { + LLSculptParams* sculpt = new LLSculptParams(); + sculpt->fromLLSD(prim_llsd["sculpt"]); + LLUUID orig = sculpt->getSculptTexture(); + bool alreadyseen = false; + for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) + { + if ((*iter) == orig) + alreadyseen = true; + } + if (alreadyseen == false) + { + llinfos << "Found a new SCULPT texture to upload " << orig << llendl; + mTexturesList.push_back(orig); + } + } + + LLSD te_llsd = prim_llsd["textures"]; + + for (text_it = te_llsd.beginArray(); text_it != te_llsd.endArray(); text_it++) + { + LLSD the_te = (*text_it); + LLTextureEntry te; + te.fromLLSD(the_te); + + te.getID(); + bool alreadyseen = false; + + for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) + { + if ((*iter) == te.getID()) + alreadyseen = true; + } + if (alreadyseen == false) + { + llinfos << "Found a new texture to upload "<< te.getID() << llendl; + mTexturesList.push_back(te.getID()); + } + } + } + } + + if (mRetexture == TRUE) + uploadNextAsset(); + else + importFirstObject(); +} + +LLVector3 LLObjectBackup::offsetAgent(LLVector3 offset) +{ + return offset * mAgentRot + mAgentPos; +} + +void LLObjectBackup::rezAgentOffset(LLVector3 offset) +{ + // This will break for a sitting agent + LLToolPlacer* mPlacer = new LLToolPlacer(); + mPlacer->setObjectType(LL_PCODE_CUBE); + //LLVector3 pos = offsetAgent(offset); + mPlacer->placeObject((S32)offset.mV[0], (S32)offset.mV[1], MASK_NONE); +} + +void LLObjectBackup::importFirstObject() +{ + mRunning = true; + show(false); + mGroupPrimImportIter = mLLSD["data"].beginArray(); + mRootRootPos = (*mGroupPrimImportIter)["root_position"]; + mObjects = mLLSD["data"].size(); + mCurObject = 1; + importNextObject(); +} + +void LLObjectBackup::importNextObject() +{ + mToSelect.clear(); + mRezCount = 0; + + mThisGroup = (*mGroupPrimImportIter)["group_body"]; + mPrimImportIter = mThisGroup.beginMap(); + + mCurPrim = 0; + mPrims = mThisGroup.size(); + updateImportNumbers(); + + LLVector3 lgpos = (*mGroupPrimImportIter)["root_position"]; + mGroupOffset = lgpos - mRootRootPos; + mRootPos = offsetAgent(LLVector3(2.0, 0.0, 0.0)); + mRootRot = ll_quaternion_from_sd((*mGroupPrimImportIter)["root_rotation"]); + + rezAgentOffset(LLVector3(0.0, 2.0, 0.0)); + // Now we must wait for the callback when ViewerObjectList gets the new objects and we have the correct number selected +} + +// This function takes a pointer to a viewerobject and applies the prim definition that prim_llsd has +void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) +{ + LLUUID id = object->getID(); + mExpectingUpdate = object->getID(); + LLSelectMgr::getInstance()->selectObjectAndFamily(object); + + if (prim_llsd.has("name")) + { + LLSelectMgr::getInstance()->selectionSetObjectName(prim_llsd["name"]); + } + + if (prim_llsd.has("description")) + { + LLSelectMgr::getInstance()->selectionSetObjectDescription(prim_llsd["description"]); + } + + if (prim_llsd.has("parent")) + { + //we are not the root node. + LLVector3 pos = prim_llsd["position"]; + LLQuaternion rot = ll_quaternion_from_sd(prim_llsd["rotation"]); + object->setPositionRegion(pos * mRootRot + mRootPos + mGroupOffset); + object->setRotation(rot * mRootRot); + } + else + { + object->setPositionRegion(mRootPos + mGroupOffset); + LLQuaternion rot=ll_quaternion_from_sd(prim_llsd["rotation"]); + object->setRotation(rot); + } + + object->setScale(prim_llsd["scale"]); + + if (prim_llsd.has("shadows")) + if (prim_llsd["shadows"].asInteger() == 1) + object->setFlags(FLAGS_CAST_SHADOWS, true); + + if (prim_llsd.has("phantom")) + if (prim_llsd["phantom"].asInteger() == 1) + object->setFlags(FLAGS_PHANTOM, true); + + if (prim_llsd.has("physical")) + if (prim_llsd["physical"].asInteger() == 1) + object->setFlags(FLAGS_USE_PHYSICS, true); + + // Volume params + LLVolumeParams volume_params = object->getVolume()->getParams(); + volume_params.fromLLSD(prim_llsd["volume"]); + object->updateVolume(volume_params); + + if (prim_llsd.has("sculpt")) + { + LLSculptParams* sculpt = new LLSculptParams(); + sculpt->fromLLSD(prim_llsd["sculpt"]); + + // TODO: check if map is valid and only set texture if map is valid and changes + + if (mAssetMap[sculpt->getSculptTexture()].notNull()) + { + LLUUID replacment = mAssetMap[sculpt->getSculptTexture()]; + sculpt->setSculptTexture(replacment); + } + + object->setParameterEntry(LLNetworkData::PARAMS_SCULPT,(LLNetworkData&)(*sculpt), true); + } + + if (prim_llsd.has("light")) + { + LLLightParams* light = new LLLightParams(); + light->fromLLSD(prim_llsd["light"]); + object->setParameterEntry(LLNetworkData::PARAMS_LIGHT,(LLNetworkData&)(*light), true); + } + + if (prim_llsd.has("flexible")) + { + LLFlexibleObjectData* flex = new LLFlexibleObjectData(); + flex->fromLLSD(prim_llsd["flexible"]); + object->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE,(LLNetworkData&)(*flex), true); + } + + // Textures + llinfos << "Processing textures for prim" << llendl; + LLSD te_llsd = prim_llsd["textures"]; + LLSD::array_iterator text_it; + U8 i = 0; + + for (text_it = te_llsd.beginArray(); text_it != te_llsd.endArray(); text_it++) + { + LLSD the_te = (*text_it); + LLTextureEntry te; + te.fromLLSD(the_te); + + if (mAssetMap[te.getID()].notNull()) + { + LLUUID replacment = mAssetMap[te.getID()]; + te.setID(replacment); + } + + object->setTE(i++, te); + } + + llinfos << "Textures done !" << llendl; + + //bump the iterator now so the callbacks hook together nicely + //if (mPrimImportIter != mThisGroup.endMap()) + // mPrimImportIter++; + + object->sendRotationUpdate(); + object->sendTEUpdate(); + object->sendShapeUpdate(); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION); + + LLSelectMgr::getInstance()->deselectAll(); +} + +// This is fired when the update packet is processed so we know the prim settings have stuck +void LLObjectBackup::primUpdate(LLViewerObject* object) +{ + if (!mRunning) + return; + + if (object != NULL) + if (object->mID != mExpectingUpdate) + return; + + mCurPrim++; + updateImportNumbers(); + mPrimImportIter++; + + LLUUID x; + mExpectingUpdate = x.null; + + if (mPrimImportIter == mThisGroup.endMap()) + { + llinfos << "Trying to link" << llendl; + + if (mToSelect.size() > 1) + { + std::reverse(mToSelect.begin(), mToSelect.end()); + // Now link + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(mToSelect, true); + LLSelectMgr::getInstance()->sendLink(); + LLViewerObject* root = mToSelect.back(); + root->setRotation(mRootRot); + } + + mCurObject++; + mGroupPrimImportIter++; + if (mGroupPrimImportIter != mLLSD["data"].endArray()) + { + importNextObject(); + return; + } + + mRunning = false; + close(); + return; + } + + LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; + + if (mToSelect.empty()) + { + llwarns << "error: ran out of objects to mod." << llendl; + return; + } + + if (mPrimImportIter != mThisGroup.endMap()) + { + //rezAgentOffset(LLVector3(1.0, 0.0, 0.0)); + LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; + mProcessIter++; + xmlToPrim(prim_llsd, *mProcessIter); + } +} + +// Callback when we rez a new object when the importer is running. +bool LLObjectBackup::newPrim(LLViewerObject* pobject) +{ + if (mRunning) + { + mRezCount++; + mToSelect.push_back(pobject); + updateImportNumbers(); + mPrimImportIter++; + + pobject->setPosition(offsetAgent(LLVector3(0.0, 1.0, 0.0))); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); + + if (mPrimImportIter != mThisGroup.endMap()) + { + rezAgentOffset(LLVector3(1.0, 0.0 ,0.0)); + } + else + { + llinfos << "All prims rezzed, moving to build stage" << llendl; + // Deselecting is required to ensure that the first child prim + // in the link set (which is also the last rezzed prim and thus + // currently selected) will be properly renamed and desced. + LLSelectMgr::getInstance()->deselectAll(); + mPrimImportIter = mThisGroup.beginMap(); + LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; + mProcessIter = mToSelect.begin(); + xmlToPrim(prim_llsd, *mProcessIter); + } + } + return true; +} + +void LLObjectBackup::updateMap(LLUUID uploaded_asset) +{ + if (mCurrentAsset.isNull()) + return; + + llinfos << "Mapping " << mCurrentAsset << " to " << uploaded_asset << llendl; + mAssetMap.insert(std::pair(mCurrentAsset, uploaded_asset)); +} + +void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, + std::string name, std::string desc, S32 compression_info, + LLAssetType::EType destination_folder_type, + LLInventoryType::EType inv_type, U32 next_owner_perm, + const std::string& display_name, + LLAssetStorage::LLStoreAssetCallback callback, + void *userdata) +{ + if (gDisconnected) + { + return; + } + + LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + + // At this point, we're ready for the upload. + std::string upload_message = "Uploading...\n\n"; + upload_message.append(display_name); + LLUploadDialog::modalUploadDialog(upload_message); + + std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); + if (!url.empty()) + { + LLSD body; + body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type); + body["asset_type"] = LLAssetType::lookup(asset_type); + body["inventory_type"] = LLInventoryType::lookup(inv_type); + body["name"] = name; + body["description"] = desc; + + std::ostringstream llsdxml; + LLSDSerialize::toXML(body, llsdxml); + lldebugs << "posting body to capability: " << llsdxml.str() << llendl; + //LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); + LLHTTPClient::post(url, body, new importResponder(body, uuid, asset_type)); + } + else + { + llinfos << "NewAgentInventory capability not found. Can't upload !" << llendl; + } +} + +void LLObjectBackup::uploadNextAsset() +{ + if (mTexturesList.empty()) + { + llinfos << "Texture list is empty, moving to rez stage." << llendl; + mCurrentAsset = LLUUID::null; + importFirstObject(); + return; + } + + updateImportNumbers(); + + std::list::iterator iter; + iter = mTexturesList.begin(); + LLUUID id = *iter; + mTexturesList.pop_front(); + + llinfos << "Got texture ID " << id << ": trying to upload" << llendl; + + mCurrentAsset = id; + std::string struid; + id.toString(struid); + std::string filename = mFolder + "//" + struid; + LLAssetID uuid; + LLTransactionID tid; + + // generate a new transaction ID for this asset + tid.generate(); + uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + + S32 file_size; + LLAPRFile outfile; + outfile.open(filename, LL_APR_RB, LLAPRFile::global, &file_size); + if (outfile.getFileHandle()) + { + const S32 buf_size = 65536; + U8 copy_buf[buf_size]; + LLVFile file(gVFS, uuid, LLAssetType::AT_TEXTURE, LLVFile::WRITE); + file.setMaxSize(file_size); + while ((file_size = outfile.read(copy_buf, buf_size))) + { + file.write(copy_buf, file_size); + } + outfile.close(); + } + else + { + llwarns << "Unable to access output file " << filename << llendl; + uploadNextAsset(); + return; + } + + myupload_new_resource(tid, LLAssetType::AT_TEXTURE, struid, struid, 0, + LLAssetType::AT_TEXTURE, LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), + 0x0, "Uploaded texture", NULL, NULL); +} diff --git a/indra/newview/llviewerobjectbackup.h b/indra/newview/llviewerobjectbackup.h new file mode 100755 index 000000000..46ca5f916 --- /dev/null +++ b/indra/newview/llviewerobjectbackup.h @@ -0,0 +1,176 @@ +/** + * @file llviewerobjectbackup.h + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerinventory.h" + +enum export_states { + EXPORT_INIT, + EXPORT_STRUCTURE, + EXPORT_TEXTURES, + EXPORT_LLSD, + EXPORT_DONE, + EXPORT_FAILED +}; + +class LLObjectBackup : public LLFloater +{ +public: + virtual ~LLObjectBackup(); + + // Floater stuff + virtual void show(bool exporting); + virtual void draw(); + virtual void onClose(bool app_quitting); + + // Static accessor + static LLObjectBackup* getInstance(); + + // Export idle callback + static void exportWorker(void *userdata); + + // Import entry point + void importObject(bool upload=FALSE); + + // Export entry point + void exportObject(); + + // Update map from texture worker + void updateMap(LLUUID uploaded_asset); + + // Move to next texture upload + void uploadNextAsset(); + + // Folder public geter + std::string getfolder() { return mFolder; }; + + // Prim updated callback + void primUpdate(LLViewerObject* object); + + // New prim call back + bool newPrim(LLViewerObject* pobject); + + static const U32 TEXTURE_OK = 0x00; + static const U32 TEXTURE_BAD_PERM = 0x01; + static const U32 TEXTURE_MISSING = 0x02; + static const U32 TEXTURE_BAD_ENCODING = 0x04; + static const U32 TEXTURE_IS_NULL = 0x08; + static const U32 TEXTURE_SAVED_FAILED = 0x10; + + // Is ready for next texture? + bool mNextTextureReady; + + // Export state machine + enum export_states mExportState; + + // Export result flags for textures. + U32 mNonExportedTextures; + +private: + // Static singleton stuff + LLObjectBackup(); + static LLObjectBackup* sInstance; + + // Update the floater with status numbers + void updateImportNumbers(); + void updateExportNumbers(); + + // Permissions stuff. + bool validatePerms(const LLPermissions* item_permissions); + LLUUID validateTextureID(LLUUID asset_id); + + // Convert a selection list of objects to LLSD + LLSD primsToLLSD(LLViewerObject::child_list_t child_list); + + // Start the import process + void importFirstObject(); + + // Move to the next import group + void importNextObject(); + + // Export the next texture in list + void exportNextTexture(); + + // Apply LLSD to object + void xmlToPrim(LLSD prim_llsd, LLViewerObject* pobject); + + // Rez a prim at a given position (note not agent offset X/Y screen for raycast) + void rezAgentOffset(LLVector3 offset); + + // Get an offset from the agent based on rotation and current pos + LLVector3 offsetAgent(LLVector3 offset); + + // Are we active flag + bool mRunning; + + // File and folder name control + std::string mFileName; + std::string mFolder; + + // True if we need to rebase the assets + bool mRetexture; + + // Counts of import and export objects and prims + U32 mObjects; + U32 mCurObject; + U32 mPrims; + U32 mCurPrim; + + // No prims rezed + U32 mRezCount; + + // Rebase map + std::map mAssetMap; + + // Export texture list + std::list mTexturesList; + + // Import object tracking + std::vector mToSelect; + std::vector::iterator mProcessIter; + + // Working LLSD holders + LLUUID mCurrentAsset; + LLSD mLLSD; + LLSD mThisGroup; + LLUUID mExpectingUpdate; + + // Working llsd itterators for objects and linksets + LLSD::map_const_iterator mPrimImportIter; + LLSD::array_const_iterator mGroupPrimImportIter; + + // Root pos and rotation and central root pos for link set + LLVector3 mRootPos; + LLQuaternion mRootRot; + LLVector3 mRootRootPos; + LLVector3 mGroupOffset; + + // Agent inital pos and rot when starting import + LLVector3 mAgentPos; + LLQuaternion mAgentRot; +}; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 167a3b9bd..80000d21a 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -75,9 +75,7 @@ #include "llappviewer.h" -// -#include "llimportobject.h" -// +#include "llviewerobjectbackup.h" extern F32 gMinObjectDistance; extern BOOL gAnimateTextures; @@ -251,6 +249,11 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, { gPipeline.addObject(objectp); } + else + { + LLObjectBackup::getInstance()->primUpdate(objectp); + } + // Also sets the approx. pixel area objectp->setPixelAreaAndAngle(gAgent); @@ -276,6 +279,8 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, objectp->mCreateSelected = false; gViewerWindow->getWindow()->decBusyCount(); gViewerWindow->getWindow()->setCursor( UI_CURSOR_ARROW ); + + LLObjectBackup::getInstance()->newPrim(objectp); } } @@ -548,28 +553,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated); } - // - if(justCreated && LLXmlImport::sImportInProgress) - { - if(objectp) - { - LLViewerObject* parent = (LLViewerObject*)objectp->getParent(); - if(parent) - { - if(parent->getID() == gAgent.getID()) - { - LLXmlImport::onNewAttachment(objectp); - } - } - else if( objectp->permYouOwner() - && (objectp->getPCode() == LLXmlImport::sSupplyParams->getPCode()) - && (objectp->getScale() == LLXmlImport::sSupplyParams->getScale())) - { - LLXmlImport::onNewPrim(objectp); - } - } - } - // objectp->setLastUpdateType(update_type); objectp->setLastUpdateCached(cached); diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 75e0f2a62..f83fa4dbb 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -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 diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index 4ad882b8b..253ae97b0 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -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; } diff --git a/indra/newview/skins/default/xui/en-us/floater_avatar_textures.xml b/indra/newview/skins/default/xui/en-us/floater_avatar_textures.xml index 5236be1de..e83fb1904 100644 --- a/indra/newview/skins/default/xui/en-us/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/en-us/floater_avatar_textures.xml @@ -1,63 +1,45 @@ - - - Baked Textures - - - Composite Textures - - +