From c7db5122c8b7e803e0c3c05b82c99ab1f715935f Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Thu, 4 Sep 2014 17:31:11 -0400 Subject: [PATCH 01/15] Fix Issue 1653: Using Search Box causes crash --- indra/newview/llfloaterdirectory.cpp | 10 ++++++++-- indra/newview/llfloaterdirectory.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/indra/newview/llfloaterdirectory.cpp b/indra/newview/llfloaterdirectory.cpp index ce2f71e16..978ccf32b 100644 --- a/indra/newview/llfloaterdirectory.cpp +++ b/indra/newview/llfloaterdirectory.cpp @@ -455,13 +455,13 @@ void LLFloaterDirectory::requestClassifieds() void LLFloaterDirectory::searchInAll(const std::string& search_text) { + start(); LLPanelDirFindAllInterface::search(sInstance->mFindAllPanel, search_text); performQueryOn2("classified_panel", search_text); performQueryOn2("events_panel", search_text); performQueryOn2("groups_panel", search_text); performQueryOn2("people_panel", search_text); performQueryOn2("places_panel", search_text); - sInstance->open(); } void LLFloaterDirectory::showFindAll(const std::string& search_text) @@ -583,7 +583,7 @@ void LLFloaterDirectory::focusCurrentPanel() } // static -void LLFloaterDirectory::showPanel(const std::string& tabname) +void LLFloaterDirectory::start() { // This function gets called when web browser clicks are processed, // so we don't delete the existing panel, which would delete the @@ -593,6 +593,12 @@ void LLFloaterDirectory::showPanel(const std::string& tabname) sInstance = new LLFloaterDirectory("directory"); } sInstance->open(); /*Flawfinder: ignore*/ +} + +// static +void LLFloaterDirectory::showPanel(const std::string& tabname) +{ + start(); sInstance->childShowTab("Directory Tabs", tabname); sInstance->focusCurrentPanel(); } diff --git a/indra/newview/llfloaterdirectory.h b/indra/newview/llfloaterdirectory.h index 0f5f1b501..c36ce412b 100644 --- a/indra/newview/llfloaterdirectory.h +++ b/indra/newview/llfloaterdirectory.h @@ -94,6 +94,7 @@ public: private: static void performQueryOn(const std::string& name, const std::string& search_text); static void performQueryOn2(const std::string& name, const std::string& search_text); + static void start(); static void showPanel(const std::string& tabname); /*virtual*/ void onClose(bool app_quitting); void focusCurrentPanel(); From 71d78425be944fb5039b718f113316df7a2f8e1f Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Thu, 4 Sep 2014 18:35:28 -0400 Subject: [PATCH 02/15] Preload trash icon Solves the issue where the remove saved login button has nothing on it --- indra/newview/skins/default/textures/textures.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index fb9c6c1e3..574f2b3a7 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -122,7 +122,7 @@ - + From e62ef91404bb1b062fe0afb5a00c2779034b4293 Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Sat, 6 Sep 2014 18:42:24 -0400 Subject: [PATCH 03/15] Fix sex radio: Now let's hear some kinky tunes~ --- indra/newview/skins/default/xui/en-us/floater_customize.xml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/indra/newview/skins/default/xui/en-us/floater_customize.xml b/indra/newview/skins/default/xui/en-us/floater_customize.xml index b4eeaf48f..bdd0065cd 100644 --- a/indra/newview/skins/default/xui/en-us/floater_customize.xml +++ b/indra/newview/skins/default/xui/en-us/floater_customize.xml @@ -47,12 +47,10 @@ name="Legs" scale_image="true" width="82" /> - + Female - + Male From f38754d0d67c68eabf30f59b5dd983675cf50315 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 7 Sep 2014 15:55:53 -0500 Subject: [PATCH 04/15] Fixed an alignment issue with LLAvatarJointCollisionVolume array. Thanks Henri. --- indra/llappearance/llavatarappearance.cpp | 48 +-- indra/llappearance/llavatarappearance.h | 4 +- indra/llappearance/llpolymorph.cpp | 6 +- indra/newview/llfloaterperms.cpp | 388 ++++++++-------------- 4 files changed, 164 insertions(+), 282 deletions(-) diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 3d3420961..d26b45208 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -182,9 +182,6 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : } mIsBuilt = FALSE; - - mNumCollisionVolumes = 0; - mCollisionVolumes = NULL; } // virtual @@ -294,7 +291,7 @@ LLAvatarAppearance::~LLAvatarAppearance() mJointMap.clear(); clearSkeleton(); - deleteAndClearArray(mCollisionVolumes); + clearCollisionVolumes(); std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer()); mPolyMeshes.clear(); @@ -575,12 +572,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent } else // collision volume { - if (volume_num >= (S32)mNumCollisionVolumes) + if (volume_num >= (S32)mCollisionVolumes.size()) { llwarns << "Too many bones" << llendl; return FALSE; } - joint = (&mCollisionVolumes[volume_num]); + joint = (mCollisionVolumes[volume_num]); joint->setName( info->mName ); } @@ -1250,12 +1247,12 @@ LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_of return LLVector3::zero; } - if (joint_index > mNumCollisionVolumes) + if (joint_index > (S32)mCollisionVolumes.size()) { return LLVector3::zero; } - return mCollisionVolumes[joint_index].getVolumePos(volume_offset); + return mCollisionVolumes[joint_index]->getVolumePos(volume_offset); } //----------------------------------------------------------------------------- @@ -1266,12 +1263,12 @@ LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id) //SNOW-488: As mNumCollisionVolumes is a S32 and we are casting from a U32 to a S32 //to compare we also need to be sure of the wrap around case producing (S32) <0 //or in terms of the U32 an out of bounds index in the array. - if ((S32)volume_id > mNumCollisionVolumes || (S32)volume_id<0) + if ((S32)volume_id > (S32)mCollisionVolumes.size() || (S32)volume_id<0) { return NULL; } - return &mCollisionVolumes[volume_id]; + return mCollisionVolumes[volume_id]; } //----------------------------------------------------------------------------- @@ -1279,9 +1276,9 @@ LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id) //----------------------------------------------------------------------------- S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name) { - for (S32 i = 0; i < mNumCollisionVolumes; i++) + for (S32 i = 0; i < (S32)mCollisionVolumes.size(); i++) { - if (mCollisionVolumes[i].getName() == name) + if (mCollisionVolumes[i]->getName() == name) { return i; } @@ -1530,21 +1527,34 @@ LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_in return mBakedTextureDatas[baked_index].mTexLayerSet; } +void LLAvatarAppearance::clearCollisionVolumes() +{ + std::for_each(mCollisionVolumes.begin(), mCollisionVolumes.end(), + DeletePointer()); + mCollisionVolumes.clear(); +} + //----------------------------------------------------------------------------- // allocateCollisionVolumes() //----------------------------------------------------------------------------- BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num ) { - deleteAndClearArray(mCollisionVolumes); - mNumCollisionVolumes = 0; + mCollisionVolumes.reserve(num); - mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; - if (!mCollisionVolumes) + LLAvatarJointCollisionVolume* cv; + for (U32 i = 0; i < num; ++i) { - return FALSE; + cv = new LLAvatarJointCollisionVolume(); + if (cv) + { + mCollisionVolumes.push_back(cv); + } + else + { + clearCollisionVolumes(); + return false; + } } - - mNumCollisionVolumes = num; return TRUE; } diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index b3a02e410..da4e09b42 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -337,9 +337,9 @@ protected: // Collision volumes //-------------------------------------------------------------------- public: - S32 mNumCollisionVolumes; - LLAvatarJointCollisionVolume* mCollisionVolumes; + std::vector mCollisionVolumes; protected: + void clearCollisionVolumes(); BOOL allocateCollisionVolumes(U32 num); /** Physics diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index aeaf79f33..669c2e5fb 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -647,11 +647,11 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info) for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++) { LLPolyVolumeMorphInfo *volume_info = &(*iter); - for (S32 i = 0; i < avatarp->mNumCollisionVolumes; i++) + for (S32 i = 0; i < (S32)avatarp->mCollisionVolumes.size(); i++) { - if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName) + if (avatarp->mCollisionVolumes[i]->getName() == volume_info->mName) { - mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i], + mVolumeMorphs.push_back(LLPolyVolumeMorph(avatarp->mCollisionVolumes[i], volume_info->mScale, volume_info->mPos)); break; diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index aa6b76c87..a85abb1a6 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -1,7 +1,7 @@ /** * @file llfloaterperms.cpp * @brief Asset creation permission preferences. - * @author Jonathan Yap + * @author Coco * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -33,57 +33,152 @@ #include "llviewerprecompiledheaders.h" #include "lfsimfeaturehandler.h" -#include "llagent.h" #include "llcheckboxctrl.h" #include "llfloaterperms.h" #include "llnotificationsutil.h" #include "llviewercontrol.h" -#include "llviewerregion.h" #include "llviewerwindow.h" #include "lluictrlfactory.h" #include "llpermissions.h" #include "hippogridmanager.h" -extern class AIHTTPTimeoutPolicy floaterPermsResponder_timeout; - -//static -U32 LLFloaterPerms::getGroupPerms(std::string prefix) +namespace { - return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY | PERM_MOVE | PERM_MODIFY : PERM_NONE; + bool everyone_export; + void handle_checkboxes(LLUICtrl* ctrl, const LLSD& value) + { + LLPanel* view = static_cast(ctrl->getParent()); + if (ctrl->getName() == "everyone_export") + { + view->childSetEnabled("next_owner_copy", !value); + view->childSetEnabled("next_owner_modify", !value); + view->childSetEnabled("next_owner_transfer", !value); + } + else + { + if (ctrl->getName() == "next_owner_copy") + { + if (!value) // Implements fair use + gSavedSettings.setBOOL("NextOwnerTransfer", true); + view->childSetEnabled("next_owner_transfer", value); + } + if (!value) // If any of these are unchecked, export can no longer be checked. + view->childSetEnabled("everyone_export", false); + else + view->childSetEnabled("everyone_export", LFSimFeatureHandler::instance().simSupportsExport() && (LLFloaterPerms::getNextOwnerPerms() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); + } + } } -//static +LLFloaterPerms::LLFloaterPerms(const LLSD& seed) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); +} + +BOOL LLFloaterPerms::postBuild() +{ + //handle_checkboxes + { + bool export_support = LFSimFeatureHandler::instance().simSupportsExport(); + const U32 next_owner_perms = getNextOwnerPerms(); + childSetEnabled("everyone_export", export_support && (next_owner_perms & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); + if (!gHippoGridManager->getCurrentGrid()->isSecondLife()) + childSetVisible("everyone_export", false); + + if (!(next_owner_perms & PERM_COPY)) + { + childSetEnabled("next_owner_transfer", false); + } + else if (export_support) + { + bool export_off = !gSavedPerAccountSettings.getBOOL("EveryoneExport"); + childSetEnabled("next_owner_copy", export_off); + childSetEnabled("next_owner_modify", export_off); + childSetEnabled("next_owner_transfer", export_off); + } + else // Set EveryoneExport false, just in case. + gSavedPerAccountSettings.setBOOL("EveryoneExport", false); + } + childSetAction("help", onClickHelp, this); + childSetAction("ok", onClickOK, this); + childSetAction("cancel", onClickCancel, this); + getChild("next_owner_copy")->setCommitCallback(handle_checkboxes); + getChild("next_owner_modify")->setCommitCallback(handle_checkboxes); + getChild("next_owner_transfer")->setCommitCallback(handle_checkboxes); + getChild("everyone_export")->setCommitCallback(handle_checkboxes); + + refresh(); + + return TRUE; +} + +//static +void LLFloaterPerms::onClickOK(void* data) +{ + LLFloaterPerms* self = static_cast(data); + self->ok(); + self->close(); +} + +//static +void LLFloaterPerms::onClickCancel(void* data) +{ + LLFloaterPerms* self = static_cast(data); + self->cancel(); + self->close(); +} + +void LLFloaterPerms::ok() +{ + refresh(); // Changes were already applied to saved settings. Refreshing internal values makes it official. +} + +void LLFloaterPerms::cancel() +{ + gSavedSettings.setBOOL("ShareWithGroup", mShareWithGroup); + gSavedSettings.setBOOL("EveryoneCopy", mEveryoneCopy); + gSavedSettings.setBOOL("NextOwnerCopy", mNextOwnerCopy); + gSavedSettings.setBOOL("NextOwnerModify", mNextOwnerModify); + gSavedSettings.setBOOL("NextOwnerTransfer", mNextOwnerTransfer); + gSavedPerAccountSettings.setBOOL("EveryoneExport", everyone_export); +} + +void LLFloaterPerms::refresh() +{ + mShareWithGroup = gSavedSettings.getBOOL("ShareWithGroup"); + mEveryoneCopy = gSavedSettings.getBOOL("EveryoneCopy"); + mNextOwnerCopy = gSavedSettings.getBOOL("NextOwnerCopy"); + mNextOwnerModify = gSavedSettings.getBOOL("NextOwnerModify"); + mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer"); + everyone_export = gSavedPerAccountSettings.getBOOL("EveryoneExport"); +} + +void LLFloaterPerms::onClose(bool app_quitting) +{ + // Cancel any unsaved changes before closing. + // Note: when closed due to the OK button this amounts to a no-op. + cancel(); + LLFloater::onClose(app_quitting); +} + +//static +U32 LLFloaterPerms::getGroupPerms(std::string prefix) +{ + return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY : PERM_NONE; +} + +//static U32 LLFloaterPerms::getEveryonePerms(std::string prefix) { U32 flags = PERM_NONE; - if (prefix != "Bulk" && LFSimFeatureHandler::instance().simSupportsExport() && prefix.empty() && gSavedPerAccountSettings.getBOOL(prefix+"EveryoneExport")) // Singu TODO: Bulk? + if (LFSimFeatureHandler::instance().simSupportsExport() && prefix.empty() && gSavedPerAccountSettings.getBOOL("EveryoneExport")) // TODO: Bulk enable export? flags |= PERM_EXPORT; if (gSavedSettings.getBOOL(prefix+"EveryoneCopy")) flags |= PERM_COPY; return flags; } -//static -U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix) -{ - // Sets bits for permissions that are off - U32 flags = PERM_MOVE; - if (!gSavedSettings.getBOOL(prefix+"NextOwnerCopy")) - { - flags |= PERM_COPY; - } - if (!gSavedSettings.getBOOL(prefix+"NextOwnerModify")) - { - flags |= PERM_MODIFY; - } - if (!gSavedSettings.getBOOL(prefix+"NextOwnerTransfer")) - { - flags |= PERM_TRANSFER; - } - return flags; -} - -//static +//static U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) { U32 flags = PERM_MOVE; @@ -102,232 +197,9 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) return flags; } -namespace + +//static +void LLFloaterPerms::onClickHelp(void* data) { - void handle_checkboxes(LLView* view, const std::string& ctrl_name, const LLSD& value, const std::string& type) - { - if (ctrl_name == type+"everyone_export") - { - view->getChildView(type+"next_owner_copy")->setEnabled(!value); - view->getChildView(type+"next_owner_modify")->setEnabled(!value); - view->getChildView(type+"next_owner_transfer")->setEnabled(!value); - } - else - { - if (ctrl_name == type+"next_owner_copy") - { - if (!value) // Implements fair use - gSavedSettings.setBOOL(type+"NextOwnerTransfer", true); - view->getChildView(type+"next_owner_transfer")->setEnabled(value); - } - if (!value) // If any of these are unchecked, export can no longer be checked. - view->getChildView(type+"everyone_export")->setEnabled(false); - else - view->getChildView(type+"everyone_export")->setEnabled(LFSimFeatureHandler::instance().simSupportsExport() && (LLFloaterPerms::getNextOwnerPerms(type) & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); - } - } -} - -static bool mCapSent = false; - -LLFloaterPermsDefault::LLFloaterPermsDefault(const LLSD& seed) - : LLFloater() -{ - mCommitCallbackRegistrar.add("PermsDefault.OK", boost::bind(&LLFloaterPermsDefault::onClickOK, this)); - mCommitCallbackRegistrar.add("PermsDefault.Cancel", boost::bind(&LLFloaterPermsDefault::onClickCancel, this)); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); -} - -// String equivalents of enum Categories - initialization order must match enum order! -const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] = -{ - "Objects", - "Uploads", - "Scripts", - "Notecards", - "Gestures", - "Wearables" -}; - -void LLFloaterPermsDefault::initCheckboxes(bool export_support, const std::string& type) -{ - const U32 next_owner_perms = LLFloaterPerms::getNextOwnerPerms(type); - getChildView(type + "everyone_export")->setEnabled(export_support && (next_owner_perms & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); - - if (!(next_owner_perms & PERM_COPY)) - { - getChildView(type + "next_owner_transfer")->setEnabled(false); - } - else if (export_support) - { - bool export_off = !gSavedPerAccountSettings.getBOOL(type+"EveryoneExport"); - getChildView(type + "next_owner_copy")->setEnabled(export_off); - getChildView(type + "next_owner_modify")->setEnabled(export_off); - getChildView(type + "next_owner_transfer")->setEnabled(export_off); - } - else // Set type+EveryoneExport false, just in case. - gSavedPerAccountSettings.setBOOL(type+"EveryoneExport", false); -} - -BOOL LLFloaterPermsDefault::postBuild() -{ - //handle_checkboxes - bool export_support = LFSimFeatureHandler::instance().simSupportsExport(); - bool is_sl = gHippoGridManager->getCurrentGrid()->isSecondLife(); - for (S32 i = 0; i < CAT_LAST; ++i) - { - const std::string& type(sCategoryNames[i]); - initCheckboxes(export_support, type); - commit_callback_t handle_checks(boost::bind(handle_checkboxes, this, boost::bind(&LLView::getName, _1), _2, type)); - getChild(type + "next_owner_copy")->setCommitCallback(handle_checks); - getChild(type + "next_owner_modify")->setCommitCallback(handle_checks); - getChild(type + "next_owner_transfer")->setCommitCallback(handle_checks); - if (is_sl) - getChildView(type + "everyone_export")->setVisible(false); - else - getChild(type + "everyone_export")->setCommitCallback(handle_checks); - } - if (is_sl) - { - LLView* view(getChildView("ExportationLabel")); - S32 shift(view->getRect().getWidth()); // Determine size of export area - LLRect rect(getRect()); - rect.mRight -= shift; - setRect(rect); // Cut off the export side - view->setVisible(false); // Hide label - // Move bottom buttons over so they look nice. - shift /= -2; - view = getChildView("ok"); - rect = view->getRect(); - rect.translate(shift, 0); - view->setRect(rect); - view = getChildView("cancel"); - rect = view->getRect(); - rect.translate(shift, 0); - view->setRect(rect); - } - - refresh(); - - return TRUE; -} - -void LLFloaterPermsDefault::onClickOK() -{ - ok(); - close(); -} - -void LLFloaterPermsDefault::onClickCancel() -{ - cancel(); - close(); -} - -class LLFloaterPermsResponder : public LLHTTPClient::ResponderWithResult -{ -public: - LLFloaterPermsResponder() : LLHTTPClient::ResponderWithResult() {} -private: - static std::string sPreviousReason; - - void httpFailure(void) - { - // Prevent 404s from annoying the user all the tme - if (mStatus == HTTP_NOT_FOUND) - LL_INFOS("FloaterPermsResponder") << "Failed to send default permissions to simulator. 404, reason: " << mReason << LL_ENDL; - else - // - // Do not display the same error more than once in a row - if (mReason != sPreviousReason) - { - sPreviousReason = mReason; - LLSD args; - args["REASON"] = mReason; - LLNotificationsUtil::add("DefaultObjectPermissions", args); - } - } - void httpSuccess(void) - { - // Since we have had a successful POST call be sure to display the next error message - // even if it is the same as a previous one. - sPreviousReason = ""; - mCapSent = true; - LL_INFOS("FloaterPermsResponder") << "Sent default permissions to simulator" << LL_ENDL; - } - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy() const { return floaterPermsResponder_timeout; } - /*virtual*/ char const* getName() const { return "LLFloaterPermsResponder"; } -}; - -std::string LLFloaterPermsResponder::sPreviousReason; - -void LLFloaterPermsDefault::sendInitialPerms() -{ - if (!mCapSent) - { - updateCap(); - } -} - -void LLFloaterPermsDefault::updateCap() -{ - std::string object_url = gAgent.getRegion()->getCapability("AgentPreferences"); - - if (!object_url.empty()) - { - LLSD report = LLSD::emptyMap(); - report["default_object_perm_masks"]["Group"] = - (LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]); - report["default_object_perm_masks"]["Everyone"] = - (LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]); - report["default_object_perm_masks"]["NextOwner"] = - (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]); - - LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder()); - } -} - -void LLFloaterPermsDefault::ok() -{ - // Changes were already applied to saved settings. - // Refreshing internal values makes it official. - refresh(); - - // We know some setting has changed but not which one. Just in case it was a setting for - // object permissions tell the server what the values are. - updateCap(); -} - -void LLFloaterPermsDefault::cancel() -{ - for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++) - { - gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]); - gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]); - gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerCopy", mNextOwnerCopy[iter]); - gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerModify", mNextOwnerModify[iter]); - gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerTransfer", mNextOwnerTransfer[iter]); - gSavedPerAccountSettings.setBOOL(sCategoryNames[iter]+"EveryoneExport", mEveryoneExport[iter]); - } -} - -void LLFloaterPermsDefault::refresh() -{ - for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++) - { - mShareWithGroup[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"ShareWithGroup"); - mEveryoneCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"EveryoneCopy"); - mNextOwnerCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerCopy"); - mNextOwnerModify[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerModify"); - mNextOwnerTransfer[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerTransfer"); - mEveryoneExport[iter] = gSavedPerAccountSettings.getBOOL(sCategoryNames[iter]+"EveryoneExport"); - } -} - -void LLFloaterPermsDefault::onClose(bool app_quitting) -{ - // Cancel any unsaved changes before closing. - // Note: when closed due to the OK button this amounts to a no-op. - cancel(); - LLFloater::onClose(app_quitting); + LLNotificationsUtil::add("ClickUploadHelpPermissions"); } From a5ac768540834cd10d2a0fae565245cf2538e56b Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Tue, 9 Sep 2014 12:38:29 -0400 Subject: [PATCH 05/15] Don't play empty audio urls. --- indra/newview/llmediafilter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/llmediafilter.cpp b/indra/newview/llmediafilter.cpp index 56d01e422..528dfc86f 100644 --- a/indra/newview/llmediafilter.cpp +++ b/indra/newview/llmediafilter.cpp @@ -101,7 +101,6 @@ void LLMediaFilter::filterAudioUrl(const std::string& url) { if (url.empty()) { - gAudiop->startInternetStream(url); return; } if (url == mCurrentAudioURL) return; From e95c0a4631856fc72c0d7a75f2e539f0c14b74d1 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 9 Sep 2014 20:44:00 -0500 Subject: [PATCH 06/15] Revert some bogus changes in f38754d0d67c68eabf30f59b5dd983675cf50315. Not sure where these changes came from. --- indra/newview/llfloaterperms.cpp | 386 ++++++++++++++++++++----------- 1 file changed, 257 insertions(+), 129 deletions(-) diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index a85abb1a6..aa6b76c87 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -1,7 +1,7 @@ /** * @file llfloaterperms.cpp * @brief Asset creation permission preferences. - * @author Coco + * @author Jonathan Yap * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -33,152 +33,57 @@ #include "llviewerprecompiledheaders.h" #include "lfsimfeaturehandler.h" +#include "llagent.h" #include "llcheckboxctrl.h" #include "llfloaterperms.h" #include "llnotificationsutil.h" #include "llviewercontrol.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "lluictrlfactory.h" #include "llpermissions.h" #include "hippogridmanager.h" -namespace -{ - bool everyone_export; - void handle_checkboxes(LLUICtrl* ctrl, const LLSD& value) - { - LLPanel* view = static_cast(ctrl->getParent()); - if (ctrl->getName() == "everyone_export") - { - view->childSetEnabled("next_owner_copy", !value); - view->childSetEnabled("next_owner_modify", !value); - view->childSetEnabled("next_owner_transfer", !value); - } - else - { - if (ctrl->getName() == "next_owner_copy") - { - if (!value) // Implements fair use - gSavedSettings.setBOOL("NextOwnerTransfer", true); - view->childSetEnabled("next_owner_transfer", value); - } - if (!value) // If any of these are unchecked, export can no longer be checked. - view->childSetEnabled("everyone_export", false); - else - view->childSetEnabled("everyone_export", LFSimFeatureHandler::instance().simSupportsExport() && (LLFloaterPerms::getNextOwnerPerms() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); - } - } -} +extern class AIHTTPTimeoutPolicy floaterPermsResponder_timeout; -LLFloaterPerms::LLFloaterPerms(const LLSD& seed) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); -} - -BOOL LLFloaterPerms::postBuild() -{ - //handle_checkboxes - { - bool export_support = LFSimFeatureHandler::instance().simSupportsExport(); - const U32 next_owner_perms = getNextOwnerPerms(); - childSetEnabled("everyone_export", export_support && (next_owner_perms & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); - if (!gHippoGridManager->getCurrentGrid()->isSecondLife()) - childSetVisible("everyone_export", false); - - if (!(next_owner_perms & PERM_COPY)) - { - childSetEnabled("next_owner_transfer", false); - } - else if (export_support) - { - bool export_off = !gSavedPerAccountSettings.getBOOL("EveryoneExport"); - childSetEnabled("next_owner_copy", export_off); - childSetEnabled("next_owner_modify", export_off); - childSetEnabled("next_owner_transfer", export_off); - } - else // Set EveryoneExport false, just in case. - gSavedPerAccountSettings.setBOOL("EveryoneExport", false); - } - childSetAction("help", onClickHelp, this); - childSetAction("ok", onClickOK, this); - childSetAction("cancel", onClickCancel, this); - getChild("next_owner_copy")->setCommitCallback(handle_checkboxes); - getChild("next_owner_modify")->setCommitCallback(handle_checkboxes); - getChild("next_owner_transfer")->setCommitCallback(handle_checkboxes); - getChild("everyone_export")->setCommitCallback(handle_checkboxes); - - refresh(); - - return TRUE; -} - -//static -void LLFloaterPerms::onClickOK(void* data) -{ - LLFloaterPerms* self = static_cast(data); - self->ok(); - self->close(); -} - -//static -void LLFloaterPerms::onClickCancel(void* data) -{ - LLFloaterPerms* self = static_cast(data); - self->cancel(); - self->close(); -} - -void LLFloaterPerms::ok() -{ - refresh(); // Changes were already applied to saved settings. Refreshing internal values makes it official. -} - -void LLFloaterPerms::cancel() -{ - gSavedSettings.setBOOL("ShareWithGroup", mShareWithGroup); - gSavedSettings.setBOOL("EveryoneCopy", mEveryoneCopy); - gSavedSettings.setBOOL("NextOwnerCopy", mNextOwnerCopy); - gSavedSettings.setBOOL("NextOwnerModify", mNextOwnerModify); - gSavedSettings.setBOOL("NextOwnerTransfer", mNextOwnerTransfer); - gSavedPerAccountSettings.setBOOL("EveryoneExport", everyone_export); -} - -void LLFloaterPerms::refresh() -{ - mShareWithGroup = gSavedSettings.getBOOL("ShareWithGroup"); - mEveryoneCopy = gSavedSettings.getBOOL("EveryoneCopy"); - mNextOwnerCopy = gSavedSettings.getBOOL("NextOwnerCopy"); - mNextOwnerModify = gSavedSettings.getBOOL("NextOwnerModify"); - mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer"); - everyone_export = gSavedPerAccountSettings.getBOOL("EveryoneExport"); -} - -void LLFloaterPerms::onClose(bool app_quitting) -{ - // Cancel any unsaved changes before closing. - // Note: when closed due to the OK button this amounts to a no-op. - cancel(); - LLFloater::onClose(app_quitting); -} - -//static +//static U32 LLFloaterPerms::getGroupPerms(std::string prefix) -{ - return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY : PERM_NONE; +{ + return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY | PERM_MOVE | PERM_MODIFY : PERM_NONE; } -//static +//static U32 LLFloaterPerms::getEveryonePerms(std::string prefix) { U32 flags = PERM_NONE; - if (LFSimFeatureHandler::instance().simSupportsExport() && prefix.empty() && gSavedPerAccountSettings.getBOOL("EveryoneExport")) // TODO: Bulk enable export? + if (prefix != "Bulk" && LFSimFeatureHandler::instance().simSupportsExport() && prefix.empty() && gSavedPerAccountSettings.getBOOL(prefix+"EveryoneExport")) // Singu TODO: Bulk? flags |= PERM_EXPORT; if (gSavedSettings.getBOOL(prefix+"EveryoneCopy")) flags |= PERM_COPY; return flags; } -//static +//static +U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix) +{ + // Sets bits for permissions that are off + U32 flags = PERM_MOVE; + if (!gSavedSettings.getBOOL(prefix+"NextOwnerCopy")) + { + flags |= PERM_COPY; + } + if (!gSavedSettings.getBOOL(prefix+"NextOwnerModify")) + { + flags |= PERM_MODIFY; + } + if (!gSavedSettings.getBOOL(prefix+"NextOwnerTransfer")) + { + flags |= PERM_TRANSFER; + } + return flags; +} + +//static U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) { U32 flags = PERM_MOVE; @@ -197,9 +102,232 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix) return flags; } - -//static -void LLFloaterPerms::onClickHelp(void* data) +namespace { - LLNotificationsUtil::add("ClickUploadHelpPermissions"); + void handle_checkboxes(LLView* view, const std::string& ctrl_name, const LLSD& value, const std::string& type) + { + if (ctrl_name == type+"everyone_export") + { + view->getChildView(type+"next_owner_copy")->setEnabled(!value); + view->getChildView(type+"next_owner_modify")->setEnabled(!value); + view->getChildView(type+"next_owner_transfer")->setEnabled(!value); + } + else + { + if (ctrl_name == type+"next_owner_copy") + { + if (!value) // Implements fair use + gSavedSettings.setBOOL(type+"NextOwnerTransfer", true); + view->getChildView(type+"next_owner_transfer")->setEnabled(value); + } + if (!value) // If any of these are unchecked, export can no longer be checked. + view->getChildView(type+"everyone_export")->setEnabled(false); + else + view->getChildView(type+"everyone_export")->setEnabled(LFSimFeatureHandler::instance().simSupportsExport() && (LLFloaterPerms::getNextOwnerPerms(type) & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); + } + } +} + +static bool mCapSent = false; + +LLFloaterPermsDefault::LLFloaterPermsDefault(const LLSD& seed) + : LLFloater() +{ + mCommitCallbackRegistrar.add("PermsDefault.OK", boost::bind(&LLFloaterPermsDefault::onClickOK, this)); + mCommitCallbackRegistrar.add("PermsDefault.Cancel", boost::bind(&LLFloaterPermsDefault::onClickCancel, this)); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); +} + +// String equivalents of enum Categories - initialization order must match enum order! +const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] = +{ + "Objects", + "Uploads", + "Scripts", + "Notecards", + "Gestures", + "Wearables" +}; + +void LLFloaterPermsDefault::initCheckboxes(bool export_support, const std::string& type) +{ + const U32 next_owner_perms = LLFloaterPerms::getNextOwnerPerms(type); + getChildView(type + "everyone_export")->setEnabled(export_support && (next_owner_perms & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); + + if (!(next_owner_perms & PERM_COPY)) + { + getChildView(type + "next_owner_transfer")->setEnabled(false); + } + else if (export_support) + { + bool export_off = !gSavedPerAccountSettings.getBOOL(type+"EveryoneExport"); + getChildView(type + "next_owner_copy")->setEnabled(export_off); + getChildView(type + "next_owner_modify")->setEnabled(export_off); + getChildView(type + "next_owner_transfer")->setEnabled(export_off); + } + else // Set type+EveryoneExport false, just in case. + gSavedPerAccountSettings.setBOOL(type+"EveryoneExport", false); +} + +BOOL LLFloaterPermsDefault::postBuild() +{ + //handle_checkboxes + bool export_support = LFSimFeatureHandler::instance().simSupportsExport(); + bool is_sl = gHippoGridManager->getCurrentGrid()->isSecondLife(); + for (S32 i = 0; i < CAT_LAST; ++i) + { + const std::string& type(sCategoryNames[i]); + initCheckboxes(export_support, type); + commit_callback_t handle_checks(boost::bind(handle_checkboxes, this, boost::bind(&LLView::getName, _1), _2, type)); + getChild(type + "next_owner_copy")->setCommitCallback(handle_checks); + getChild(type + "next_owner_modify")->setCommitCallback(handle_checks); + getChild(type + "next_owner_transfer")->setCommitCallback(handle_checks); + if (is_sl) + getChildView(type + "everyone_export")->setVisible(false); + else + getChild(type + "everyone_export")->setCommitCallback(handle_checks); + } + if (is_sl) + { + LLView* view(getChildView("ExportationLabel")); + S32 shift(view->getRect().getWidth()); // Determine size of export area + LLRect rect(getRect()); + rect.mRight -= shift; + setRect(rect); // Cut off the export side + view->setVisible(false); // Hide label + // Move bottom buttons over so they look nice. + shift /= -2; + view = getChildView("ok"); + rect = view->getRect(); + rect.translate(shift, 0); + view->setRect(rect); + view = getChildView("cancel"); + rect = view->getRect(); + rect.translate(shift, 0); + view->setRect(rect); + } + + refresh(); + + return TRUE; +} + +void LLFloaterPermsDefault::onClickOK() +{ + ok(); + close(); +} + +void LLFloaterPermsDefault::onClickCancel() +{ + cancel(); + close(); +} + +class LLFloaterPermsResponder : public LLHTTPClient::ResponderWithResult +{ +public: + LLFloaterPermsResponder() : LLHTTPClient::ResponderWithResult() {} +private: + static std::string sPreviousReason; + + void httpFailure(void) + { + // Prevent 404s from annoying the user all the tme + if (mStatus == HTTP_NOT_FOUND) + LL_INFOS("FloaterPermsResponder") << "Failed to send default permissions to simulator. 404, reason: " << mReason << LL_ENDL; + else + // + // Do not display the same error more than once in a row + if (mReason != sPreviousReason) + { + sPreviousReason = mReason; + LLSD args; + args["REASON"] = mReason; + LLNotificationsUtil::add("DefaultObjectPermissions", args); + } + } + void httpSuccess(void) + { + // Since we have had a successful POST call be sure to display the next error message + // even if it is the same as a previous one. + sPreviousReason = ""; + mCapSent = true; + LL_INFOS("FloaterPermsResponder") << "Sent default permissions to simulator" << LL_ENDL; + } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy() const { return floaterPermsResponder_timeout; } + /*virtual*/ char const* getName() const { return "LLFloaterPermsResponder"; } +}; + +std::string LLFloaterPermsResponder::sPreviousReason; + +void LLFloaterPermsDefault::sendInitialPerms() +{ + if (!mCapSent) + { + updateCap(); + } +} + +void LLFloaterPermsDefault::updateCap() +{ + std::string object_url = gAgent.getRegion()->getCapability("AgentPreferences"); + + if (!object_url.empty()) + { + LLSD report = LLSD::emptyMap(); + report["default_object_perm_masks"]["Group"] = + (LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]); + report["default_object_perm_masks"]["Everyone"] = + (LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]); + report["default_object_perm_masks"]["NextOwner"] = + (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]); + + LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder()); + } +} + +void LLFloaterPermsDefault::ok() +{ + // Changes were already applied to saved settings. + // Refreshing internal values makes it official. + refresh(); + + // We know some setting has changed but not which one. Just in case it was a setting for + // object permissions tell the server what the values are. + updateCap(); +} + +void LLFloaterPermsDefault::cancel() +{ + for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++) + { + gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]); + gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]); + gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerCopy", mNextOwnerCopy[iter]); + gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerModify", mNextOwnerModify[iter]); + gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerTransfer", mNextOwnerTransfer[iter]); + gSavedPerAccountSettings.setBOOL(sCategoryNames[iter]+"EveryoneExport", mEveryoneExport[iter]); + } +} + +void LLFloaterPermsDefault::refresh() +{ + for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++) + { + mShareWithGroup[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"ShareWithGroup"); + mEveryoneCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"EveryoneCopy"); + mNextOwnerCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerCopy"); + mNextOwnerModify[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerModify"); + mNextOwnerTransfer[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerTransfer"); + mEveryoneExport[iter] = gSavedPerAccountSettings.getBOOL(sCategoryNames[iter]+"EveryoneExport"); + } +} + +void LLFloaterPermsDefault::onClose(bool app_quitting) +{ + // Cancel any unsaved changes before closing. + // Note: when closed due to the OK button this amounts to a no-op. + cancel(); + LLFloater::onClose(app_quitting); } From df2ca052ea6c4234ddc8bc73ffc05afdc53c080c Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 9 Sep 2014 21:56:53 -0500 Subject: [PATCH 07/15] I suppose actually including llvoavatar.cpp would help too... --- indra/newview/llvoavatar.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 9e20f8ab8..95b24f7d7 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1799,10 +1799,10 @@ void LLVOAvatar::renderCollisionVolumes() { std::ostringstream ostr; LLGLDepthTest gls_depth(GL_FALSE); - for (S32 i = 0; i < mNumCollisionVolumes; i++) + for (S32 i = 0; i < (S32)mCollisionVolumes.size(); i++) { - mCollisionVolumes[i].renderCollision(); - ostr << mCollisionVolumes[i].getName() << ", "; + mCollisionVolumes[i]->renderCollision(); + ostr << mCollisionVolumes[i]->getName() << ", "; } if (mNameText.notNull()) @@ -1920,11 +1920,11 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& if (lineSegmentBoundingBox(start, end)) { - for (S32 i = 0; i < mNumCollisionVolumes; ++i) + for (S32 i = 0; i < (S32)mCollisionVolumes.size(); ++i) { - mCollisionVolumes[i].updateWorldMatrix(); + mCollisionVolumes[i]->updateWorldMatrix(); - const LLMatrix4a& mat = mCollisionVolumes[i].getXform()->getWorldMatrix(); + const LLMatrix4a& mat = mCollisionVolumes[i]->getXform()->getWorldMatrix(); LLMatrix4a inverse = mat; inverse.invert(); LLMatrix4a norm_mat = inverse; From a68983b37f1a0750c7257c63821d3c31bdb7d852 Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Wed, 10 Sep 2014 16:58:44 -0400 Subject: [PATCH 08/15] =?UTF-8?q?[Warnings]=20Fix=20=E2=80=98std::string?= =?UTF-8?q?=20{anonymous}::compute=5FCPUFamilyName(const=20char*,=20int,?= =?UTF-8?q?=20int)=E2=80=99=20defined=20but=20not=20used?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- indra/llcommon/llprocessor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index a7d2eac67..e39fa373d 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -206,6 +206,7 @@ namespace return "Unknown"; } +#if LL_LINUX std::string compute_CPUFamilyName(const char* cpu_vendor, int composed_family) { const char* intel_string = "GenuineIntel"; @@ -221,6 +222,7 @@ namespace return "Unknown"; } +#else std::string compute_CPUFamilyName(const char* cpu_vendor, int family, int ext_family) { const char* intel_string = "GenuineIntel"; @@ -239,6 +241,7 @@ namespace } return "Unknown"; } +#endif } // end unnamed namespace From ff8b4fd95ad2b64eb98f7dbb31fc163b6f6abb71 Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Thu, 11 Sep 2014 03:37:51 -0400 Subject: [PATCH 09/15] [Radar] Optimize hidden column evaluation and generation out of draw call. Please view this diff without space changes. --- indra/newview/llfloateravatarlist.cpp | 378 ++++++++++++++------------ 1 file changed, 203 insertions(+), 175 deletions(-) diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index d798540e8..d0d75dbe6 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -700,151 +700,171 @@ void LLFloaterAvatarList::refreshAvatarList() LLScrollListItem::Params element; element.value = av_id; - LLScrollListCell::Params mark; - mark.column = "marked"; - mark.type = "text"; - if (entry->isMarked()) + static const LLCachedControl hide_mark("RadarColumnMarkHidden"); + if (!hide_mark) { - mark.value = "X"; - mark.color = LLColor4::blue; - mark.font_style = "BOLD"; - } - - LLScrollListCell::Params name; - name.column = "avatar_name"; - name.type = "text"; - name.value = entry->getName(); - if (entry->isFocused()) - { - name.font_style = "BOLD"; - } - - // custom colors for certain types of avatars! - //Changed a bit so people can modify them in settings. And since they're colors, again it's possibly account-based. Starting to think I need a function just to determine that. - HgB - //name.color = gColors.getColor( "MapAvatar" ); - LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry->getPosition()); - LLUUID estate_owner = LLUUID::null; - if (parent_estate && parent_estate->isAlive()) - { - estate_owner = parent_estate->getOwner(); + LLScrollListCell::Params mark; + mark.column = "marked"; + mark.type = "text"; + if (entry->isMarked()) + { + mark.value = "X"; + mark.color = LLColor4::blue; + mark.font_style = "BOLD"; + } + element.columns.add(mark); } static const LLCachedControl unselected_color(gColors, "ScrollUnselectedColor", LLColor4(0.f, 0.f, 0.f, 0.8f)); - static LLCachedControl sDefaultListText(gColors, "DefaultListText"); - static LLCachedControl sRadarTextChatRange(gColors, "RadarTextChatRange"); - static LLCachedControl sRadarTextShoutRange(gColors, "RadarTextShoutRange"); - static LLCachedControl sRadarTextDrawDist(gColors, "RadarTextDrawDist"); - static LLCachedControl sRadarTextYoung(gColors, "RadarTextYoung"); + static const LLCachedControl sDefaultListText(gColors, "DefaultListText"); static const LLCachedControl ascent_muted_color("AscentMutedColor", LLColor4(0.7f,0.7f,0.7f,1.f)); LLColor4 color = sDefaultListText; - //Lindens are always more Linden than your friend, make that take precedence - if (mm_getMarkerColor(av_id, color)) {} - else if (LLMuteList::getInstance()->isLinden(av_id)) + // Name never hidden { - static const LLCachedControl ascent_linden_color("AscentLindenColor", LLColor4(0.f,0.f,1.f,1.f)); - color = ascent_linden_color; + LLScrollListCell::Params name; + name.column = "avatar_name"; + name.type = "text"; + name.value = entry->getName(); + if (entry->isFocused()) + { + name.font_style = "BOLD"; + } + + // custom colors for certain types of avatars! + //Changed a bit so people can modify them in settings. And since they're colors, again it's possibly account-based. Starting to think I need a function just to determine that. - HgB + //name.color = gColors.getColor( "MapAvatar" ); + LLUUID estate_owner = LLUUID::null; + if (LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry->getPosition())) + if (parent_estate->isAlive()) + estate_owner = parent_estate->getOwner(); + + //Lindens are always more Linden than your friend, make that take precedence + if (mm_getMarkerColor(av_id, color)) {} + else if (LLMuteList::getInstance()->isLinden(av_id)) + { + static const LLCachedControl ascent_linden_color("AscentLindenColor", LLColor4(0.f,0.f,1.f,1.f)); + color = ascent_linden_color; + } + //check if they are an estate owner at their current position + else if (estate_owner.notNull() && av_id == estate_owner) + { + static const LLCachedControl ascent_estate_owner_color("AscentEstateOwnerColor", LLColor4(1.f,0.6f,1.f,1.f)); + color = ascent_estate_owner_color; + } + //without these dots, SL would suck. + else if (LLAvatarActions::isFriend(av_id)) + { + static const LLCachedControl ascent_friend_color("AscentFriendColor", LLColor4(1.f,1.f,0.f,1.f)); + color = ascent_friend_color; + } + //big fat jerkface who is probably a jerk, display them as such. + else if (LLMuteList::getInstance()->isMuted(av_id)) + { + color = ascent_muted_color; + } + name.color = color*0.5f + unselected_color*0.5f; + element.columns.add(name); } - //check if they are an estate owner at their current position - else if (estate_owner.notNull() && av_id == estate_owner) - { - static const LLCachedControl ascent_estate_owner_color("AscentEstateOwnerColor", LLColor4(1.f,0.6f,1.f,1.f)); - color = ascent_estate_owner_color; - } - //without these dots, SL would suck. - else if (LLAvatarActions::isFriend(av_id)) - { - static const LLCachedControl ascent_friend_color("AscentFriendColor", LLColor4(1.f,1.f,0.f,1.f)); - color = ascent_friend_color; - } - //big fat jerkface who is probably a jerk, display them as such. - else if (LLMuteList::getInstance()->isMuted(av_id)) - { - color = ascent_muted_color; - } - name.color = color*0.5f + unselected_color*0.5f; char temp[32]; - color = sDefaultListText; - LLScrollListCell::Params dist; - dist.column = "distance"; - dist.type = "text"; - if (UnknownAltitude) + // Distance never hidden { - strcpy(temp, "?"); - if (entry->mStats[STAT_TYPE_DRAW]) + color = sDefaultListText; + LLScrollListCell::Params dist; + dist.column = "distance"; + dist.type = "text"; + static const LLCachedControl sRadarTextDrawDist(gColors, "RadarTextDrawDist"); + if (UnknownAltitude) { - color = sRadarTextDrawDist; - } - } - else - { - if (distance <= LFSimFeatureHandler::getInstance()->shoutRange()) - { - snprintf(temp, sizeof(temp), "%.1f", distance); - color = (distance > LFSimFeatureHandler::getInstance()->sayRange()) ? sRadarTextShoutRange : sRadarTextChatRange; + strcpy(temp, "?"); + if (entry->mStats[STAT_TYPE_DRAW]) + { + color = sRadarTextDrawDist; + } } else { - if (entry->mStats[STAT_TYPE_DRAW]) color = sRadarTextDrawDist; - snprintf(temp, sizeof(temp), "%d", (S32)distance); + if (distance <= LFSimFeatureHandler::getInstance()->shoutRange()) + { + static const LLCachedControl sRadarTextChatRange(gColors, "RadarTextChatRange"); + static const LLCachedControl sRadarTextShoutRange(gColors, "RadarTextShoutRange"); + snprintf(temp, sizeof(temp), "%.1f", distance); + color = (distance > LFSimFeatureHandler::getInstance()->sayRange()) ? sRadarTextShoutRange : sRadarTextChatRange; + } + else + { + if (entry->mStats[STAT_TYPE_DRAW]) color = sRadarTextDrawDist; + snprintf(temp, sizeof(temp), "%d", (S32)distance); + } } + dist.value = temp; + dist.color = color * 0.7f + unselected_color * 0.3f; // Liru: Blend testing! + //dist.color = color; + element.columns.add(dist); } - dist.value = temp; - dist.color = color * 0.7f + unselected_color * 0.3f; // Liru: Blend testing! - //dist.color = color; - LLScrollListCell::Params pos; - position -= simpos; + static const LLCachedControl hide_pos("RadarColumnPositionHidden"); + if (!hide_pos) + { + LLScrollListCell::Params pos; + position -= simpos; - S32 x(position.mdV[VX]); - S32 y(position.mdV[VY]); - if (x >= 0 && x <= width && y >= 0 && y <= width) - { - snprintf(temp, sizeof(temp), "%d, %d", x, y); + S32 x(position.mdV[VX]); + S32 y(position.mdV[VY]); + if (x >= 0 && x <= width && y >= 0 && y <= width) + { + snprintf(temp, sizeof(temp), "%d, %d", x, y); + } + else + { + temp[0] = '\0'; + if (y < 0) + { + strcat(temp, "S"); + } + else if (y > width) + { + strcat(temp, "N"); + } + if (x < 0) + { + strcat(temp, "W"); + } + else if (x > width) + { + strcat(temp, "E"); + } + } + pos.column = "position"; + pos.type = "text"; + pos.value = temp; + element.columns.add(pos); } - else - { - temp[0] = '\0'; - if (y < 0) - { - strcat(temp, "S"); - } - else if (y > width) - { - strcat(temp, "N"); - } - if (x < 0) - { - strcat(temp, "W"); - } - else if (x > width) - { - strcat(temp, "E"); - } - } - pos.column = "position"; - pos.type = "text"; - pos.value = temp; - LLScrollListCell::Params alt; - alt.column = "altitude"; - alt.type = "text"; - if (UnknownAltitude) + static const LLCachedControl hide_alt("RadarColumnAltitudeHidden"); + if (!hide_alt) { - strcpy(temp, "?"); + LLScrollListCell::Params alt; + alt.column = "altitude"; + alt.type = "text"; + if (UnknownAltitude) + { + strcpy(temp, "?"); + } + else + { + snprintf(temp, sizeof(temp), "%d", (S32)position.mdV[VZ]); + } + alt.value = temp; + element.columns.add(alt); } - else - { - snprintf(temp, sizeof(temp), "%d", (S32)position.mdV[VZ]); - } - alt.value = temp; - LLScrollListCell::Params act; static const LLCachedControl hide_act("RadarColumnActivityHidden"); if (!hide_act) { + LLScrollListCell::Params act; act.column = "activity"; act.type = "icon"; switch(entry->getActivity()) @@ -880,12 +900,13 @@ void LLFloaterAvatarList::refreshAvatarList() default: break; } + element.columns.add(act); } - LLScrollListCell::Params voice; static const LLCachedControl hide_voice("RadarColumnVoiceHidden"); if (!hide_voice) { + LLScrollListCell::Params voice; voice.column("voice"); voice.type("icon"); // transplant from llparticipantlist.cpp, update accordingly. @@ -914,71 +935,78 @@ void LLFloaterAvatarList::refreshAvatarList() voice.color(speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE ? LLColor4::transparent : speakerp->mDotColor); } } + element.columns.add(voice); } - LLScrollListCell::Params agep; - agep.column = "age"; - agep.type = "text"; - color = sDefaultListText; - std::string age = boost::lexical_cast(entry->mAge); - if (entry->mAge > -1) + static const LLCachedControl hide_age("RadarColumnAgeHidden"); + if (!hide_age) { - static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); - if ((U32)entry->mAge < sAvatarAgeAlertDays) - color = sRadarTextYoung; - } - else - { - age = "?"; - } - agep.value = age; - agep.color = color; - - int dur = difftime(time(NULL), entry->getTime()); - int hours = dur / 3600; - int mins = (dur % 3600) / 60; - int secs = (dur % 3600) % 60; - - LLScrollListCell::Params time; - time.column = "time"; - time.type = "text"; - time.value = llformat("%d:%02d:%02d", hours, mins, secs); - - LLScrollListCell::Params viewer; - viewer.column = "client"; - viewer.type = "text"; - - static const LLCachedControl avatar_name_color(gColors, "AvatarNameColor",LLColor4(0.98f, 0.69f, 0.36f, 1.f)); - color = avatar_name_color; - if (LLVOAvatar* avatarp = gObjectList.findAvatar(av_id)) - { - std::string client = SHClientTagMgr::instance().getClientName(avatarp, false); - if (client.empty()) + LLScrollListCell::Params agep; + agep.column = "age"; + agep.type = "text"; + color = sDefaultListText; + std::string age = boost::lexical_cast(entry->mAge); + if (entry->mAge > -1) { - color = unselected_color; - client = "?"; + static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); + if ((U32)entry->mAge < sAvatarAgeAlertDays) + { + static const LLCachedControl sRadarTextYoung(gColors, "RadarTextYoung"); + color = sRadarTextYoung; + } } - else SHClientTagMgr::instance().getClientColor(avatarp, false, color); - viewer.value = client.c_str(); + else + { + age = "?"; + } + agep.value = age; + agep.color = color; + element.columns.add(agep); } - else - { - viewer.value = getString("Out Of Range"); - } - //Blend to make the color show up better - viewer.color = color *.5f + unselected_color * .5f; - // Add individual column cell params to the item param - element.columns.add(mark); - element.columns.add(name); - element.columns.add(dist); - element.columns.add(pos); - element.columns.add(alt); - if (!hide_act) element.columns.add(act); - if (!hide_voice) element.columns.add(voice); - element.columns.add(agep); - element.columns.add(time); - element.columns.add(viewer); + static const LLCachedControl hide_time("RadarColumnTimeHidden"); + if (!hide_time) + { + int dur = difftime(time(NULL), entry->getTime()); + int hours = dur / 3600; + int mins = (dur % 3600) / 60; + int secs = (dur % 3600) % 60; + + LLScrollListCell::Params time; + time.column = "time"; + time.type = "text"; + time.value = llformat("%d:%02d:%02d", hours, mins, secs); + element.columns.add(time); + } + + static const LLCachedControl hide_client("RadarColumnClientHidden"); + if (!hide_client) + { + LLScrollListCell::Params viewer; + viewer.column = "client"; + viewer.type = "text"; + + static const LLCachedControl avatar_name_color(gColors, "AvatarNameColor",LLColor4(0.98f, 0.69f, 0.36f, 1.f)); + color = avatar_name_color; + if (LLVOAvatar* avatarp = gObjectList.findAvatar(av_id)) + { + std::string client = SHClientTagMgr::instance().getClientName(avatarp, false); + if (client.empty()) + { + color = unselected_color; + client = "?"; + } + else SHClientTagMgr::instance().getClientColor(avatarp, false, color); + viewer.value = client.c_str(); + } + else + { + viewer.value = getString("Out Of Range"); + } + //Blend to make the color show up better + viewer.color = color *.5f + unselected_color * .5f; + element.columns.add(viewer); + } // Add to list mAvatarList->addRow(element); From 1ee939c7f797b889187895ea31540199655fb94b Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Thu, 11 Sep 2014 03:58:23 -0400 Subject: [PATCH 10/15] [Radar] Feature Request: Add the ability to see avatar distance in avatar range alerts. To toggle this feature, right click the radar, under the Alerts submenu choose "Include distance in alerts" Cleans up code for calls to setPosition. For now only entering messages will show distance, unless testing shows that it should be otherwise. --- indra/newview/app_settings/settings.xml | 11 ++++++++ indra/newview/llfloateravatarlist.cpp | 28 ++++++++++++------- indra/newview/llfloateravatarlist.h | 2 +- .../skins/default/xui/en-us/menu_radar.xml | 4 +++ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0ea26715c..476d752ea 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7735,6 +7735,17 @@ This should be as low as possible, but too low may break functionality Value 1 + RadarAlertShowDist + + Comment + Show distance in radar announcements. + Persist + 1 + Type + Boolean + Value + 1 + RadarAlertSim Comment diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index d0d75dbe6..6b47c2680 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -68,7 +68,7 @@ extern U32 gFrameCount; namespace { - void chat_avatar_status(const std::string& name, const LLUUID& key, ERadarStatType type, bool entering) + void chat_avatar_status(const std::string& name, const LLUUID& key, ERadarStatType type, bool entering, const F32& dist) { if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) return; // RLVa:LF Don't announce people are around when blind, that cheats the system. static LLCachedControl radar_chat_alerts(gSavedSettings, "RadarChatAlerts"); @@ -96,6 +96,11 @@ namespace if (args.find("[RANGE]") != args.end()) chat.mText = self->getString("template", args); else if (chat.mText.empty()) return; + if (entering) // Note: If we decide to make this for leaving as well, change this check to dist != F32_MIN + { + static const LLCachedControl radar_show_dist("RadarAlertShowDist"); + if (radar_show_dist) chat.mText += llformat(" (%.2fm)", dist); + } chat.mFromName = name; chat.mURL = llformat("secondlife:///app/agent/%s/about",key.asString().c_str()); chat.mSourceType = CHAT_SOURCE_SYSTEM; @@ -160,7 +165,7 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); if ((U32)mAge < sAvatarAgeAlertDays) { - chat_avatar_status(mName, mID, STAT_TYPE_AGE, mStats[STAT_TYPE_AGE] = true); + chat_avatar_status(mName, mID, STAT_TYPE_AGE, mStats[STAT_TYPE_AGE] = true, (mPosition - gAgent.getPositionGlobal()).magVec()); } } // If one wanted more information that gets displayed on profiles to be displayed, here would be the place to do it. @@ -168,14 +173,18 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) } } -void LLAvatarListEntry::setPosition(const LLVector3d& position, bool this_sim, bool drawn, bool chatrange, bool shoutrange) +void LLAvatarListEntry::setPosition(const LLVector3d& position, const F32& dist, bool drawn) { mPosition = position; mFrame = gFrameCount; - if (this_sim != mStats[STAT_TYPE_SIM]) chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim); - if (drawn != mStats[STAT_TYPE_DRAW]) chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn); - if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange); - if (chatrange != mStats[STAT_TYPE_CHATRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange); + bool here(dist != F32_MIN); // F32_MIN only if dead + bool this_sim(here && (gAgent.getRegion()->pointInRegionGlobal(position) || !(LLWorld::getInstance()->positionRegionValidGlobal(position)))); + if (this_sim != mStats[STAT_TYPE_SIM]) chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim, dist); + if (drawn != mStats[STAT_TYPE_DRAW]) chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn, dist); + bool shoutrange(here && dist < LFSimFeatureHandler::getInstance()->shoutRange()); + if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange, dist); + bool chatrange(here && dist < LFSimFeatureHandler::getInstance()->sayRange()); + if (chatrange != mStats[STAT_TYPE_CHATRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange, dist); mUpdateTimer.start(); } @@ -553,8 +562,7 @@ void LLFloaterAvatarList::updateAvatarList() } // Announce position - F32 dist((position - mypos).magVec()); - entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position) || !(LLWorld::getInstance()->positionRegionValidGlobal(position)), avatarp, dist < LFSimFeatureHandler::getInstance()->sayRange(), dist < LFSimFeatureHandler::getInstance()->shoutRange()); + entry->setPosition(position, (position - mypos).magVec(), avatarp); // Mark as typing if they are typing if (avatarp && avatarp->isTyping()) entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING); @@ -621,7 +629,7 @@ void LLFloaterAvatarList::expireAvatarList() } else { - entry->setPosition(entry->getPosition(), false, false, false, false); // Dead and gone + entry->setPosition(entry->getPosition(), F32_MIN, false); // Dead and gone it = mAvatars.erase(it); } } diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 222107c12..d77231509 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -80,7 +80,7 @@ enum ACTIVITY_TYPE * Update world position. * Affects age. */ - void setPosition(const LLVector3d& position, bool this_sim, bool drawn, bool chatrange, bool shoutrange); + void setPosition(const LLVector3d& position, const F32& dist, bool drawn); const LLVector3d& getPosition() const { return mPosition; } diff --git a/indra/newview/skins/default/xui/en-us/menu_radar.xml b/indra/newview/skins/default/xui/en-us/menu_radar.xml index 2f06bbf3c..624b577c6 100644 --- a/indra/newview/skins/default/xui/en-us/menu_radar.xml +++ b/indra/newview/skins/default/xui/en-us/menu_radar.xml @@ -119,6 +119,10 @@ + + + + From 6863eb66518ff9d306915e530a2aa684417b4432 Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Thu, 11 Sep 2014 16:02:54 -0400 Subject: [PATCH 11/15] Be sure the object's inventory serial is incorrect before dirtying the inventory Thanks to Ubit for pointing this out --- indra/newview/llselectmgr.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index c10570d7d..55f723651 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5201,7 +5201,9 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data { if (node->mInventorySerial != inv_serial) { - node->getObject()->dirtyInventory(); + if (LLViewerObject* object = node->getObject()) + if (object->getInventorySerial() != inv_serial) // Singu Note: the serial number in the object may be correct. + object->dirtyInventory(); } // save texture data as soon as we get texture perms first time From e5e665b9eead26c0f47db3267a478d5ead93a5c1 Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Thu, 11 Sep 2014 18:13:11 -0400 Subject: [PATCH 12/15] Sync LLAssetUploadResponders with upstream Move LLSendTexLayerResponder into llviewertexlayer.cpp to reduce diff noise --- indra/llmessage/aihttptimeoutpolicy.cpp | 2 - indra/newview/llassetuploadresponders.cpp | 177 ++++++++-------------- indra/newview/llassetuploadresponders.h | 58 +++---- indra/newview/llfloatersnapshot.cpp | 8 +- indra/newview/llviewermenufile.cpp | 20 +-- indra/newview/llviewermenufile.h | 3 +- indra/newview/llviewertexlayer.cpp | 45 ++++++ 7 files changed, 142 insertions(+), 171 deletions(-) diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index 4434ef545..2b0b8af6b 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -905,7 +905,6 @@ AIHTTPTimeoutPolicy const* AIHTTPTimeoutPolicy::getTimeoutPolicyByName(std::stri #define P2(n, b) AIHTTPTimeoutPolicy n##_timeout(#n, b) // Policy name Policy -P(assetUploadResponder); P(assetReportHandler); P(avatarPickerResponder); P(authHandler); @@ -952,7 +951,6 @@ P2(meshPhysicsShapeResponder, connect_30s); P2(meshSkinInfoResponder, connect_30s); P(mimeDiscoveryResponder); P(moderationResponder); -P(newAgentInventoryVariablePriceResponder); P(objectCostResponder); P(physicsFlagsResponder); P(productInfoRequestResponder); diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 16dd0d4e5..178eb094f 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -37,6 +37,7 @@ #include "llagent.h" #include "llcompilequeue.h" #include "llfloaterbuycurrency.h" +#include "statemachine/aifilepicker.h" #include "llinventorydefines.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" @@ -66,8 +67,6 @@ #include "llsdutil.h" #include "llvfs.h" -#include "statemachine/aifilepicker.h" - // When uploading multiple files, don't display any of them when uploading more than this number. static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5; @@ -190,9 +189,10 @@ void on_new_single_inventory_upload_complete( LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type) -: mPostData(post_data), - mVFileID(vfile_id), - mAssetType(asset_type) +: + mPostData(post_data), + mVFileID(vfile_id), + mAssetType(asset_type) { if (!gVFS->getExists(vfile_id, asset_type)) { @@ -207,9 +207,10 @@ LLAssetUploadResponder::LLAssetUploadResponder( const LLSD &post_data, const std::string& file_name, LLAssetType::EType asset_type) -: mPostData(post_data), - mFileName(file_name), - mAssetType(asset_type) +: + mPostData(post_data), + mFileName(file_name), + mAssetType(asset_type) { } @@ -223,7 +224,7 @@ LLAssetUploadResponder::~LLAssetUploadResponder() } // virtual -void LLAssetUploadResponder::httpFailure(void) +void LLAssetUploadResponder::httpFailure() { llinfos << "LLAssetUploadResponder::error " << mStatus << " reason: " << mReason << llendl; @@ -248,15 +249,21 @@ void LLAssetUploadResponder::httpFailure(void) } //virtual -void LLAssetUploadResponder::httpSuccess(void) +void LLAssetUploadResponder::httpSuccess() { + const LLSD& content = getContent(); + if (!content.isMap()) + { + failureResult(HTTP_INTERNAL_ERROR_OTHER, "Malformed response contents", content); + return; + } lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl; - std::string state = mContent["state"]; + const std::string& state = content["state"].asString(); if (state == "upload") { - uploadUpload(mContent); + uploadUpload(content); } else if (state == "complete") { @@ -264,20 +271,20 @@ void LLAssetUploadResponder::httpSuccess(void) if (mFileName.empty()) { // rename the file in the VFS to the actual asset id - // llinfos << "Changing uploaded asset UUID to " << mContent["new_asset"].asUUID() << llendl; - gVFS->renameFile(mVFileID, mAssetType, mContent["new_asset"].asUUID(), mAssetType); + // LL_INFOS() << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << LL_ENDL; + gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType); } - uploadComplete(mContent); + uploadComplete(content); } else { - uploadFailure(mContent); + uploadFailure(content); } } void LLAssetUploadResponder::uploadUpload(const LLSD& content) { - std::string uploader = content["uploader"]; + const std::string& uploader = content["uploader"].asString(); if (mFileName.empty()) { LLHTTPClient::postFile(uploader, mVFileID, mAssetType, this); @@ -293,7 +300,7 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content) // remove the "Uploading..." message LLUploadDialog::modalUploadFinished(); - std::string reason = content["state"]; + const std::string& reason = content["state"].asString(); // deal with L$ errors if (reason == "insufficient funds") { @@ -316,10 +323,8 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content) LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, - LLAssetType::EType asset_type, - void (*callback)(bool, void*), - void* user_data) - : LLAssetUploadResponder(post_data, vfile_id, asset_type), mCallBack(callback), mUserData(user_data) + LLAssetType::EType asset_type) + : LLAssetUploadResponder(post_data, vfile_id, asset_type) { } @@ -327,17 +332,13 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type) - : LLAssetUploadResponder(post_data, file_name, asset_type), mCallBack(NULL), mUserData(NULL) + : LLAssetUploadResponder(post_data, file_name, asset_type) { } // virtual -void LLNewAgentInventoryResponder::httpFailure(void) +void LLNewAgentInventoryResponder::httpFailure() { - if (mCallBack) - { - (*mCallBack)(false, mUserData); - } LLAssetUploadResponder::httpFailure(); //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE); } @@ -346,10 +347,6 @@ void LLNewAgentInventoryResponder::httpFailure(void) //virtual void LLNewAgentInventoryResponder::uploadFailure(const LLSD& content) { - if (mCallBack) - { - (*mCallBack)(false, mUserData); - } LLAssetUploadResponder::uploadFailure(content); //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], FALSE); @@ -360,14 +357,9 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) { lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; - if (mCallBack) - { - (*mCallBack)(true, mUserData); - } - //std::ostringstream llsdxml; //LLSDSerialize::toXML(content, llsdxml); - //llinfos << "upload complete content:\n " << llsdxml.str() << llendl; + //LL_INFOS() << "upload complete content:\n " << llsdxml.str() << LL_ENDL; LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); @@ -456,57 +448,6 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) */ } -LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type, - LLBakedUploadData * baked_upload_data) : - LLAssetUploadResponder(post_data, vfile_id, asset_type), - mBakedUploadData(baked_upload_data) -{ -} - -LLSendTexLayerResponder::~LLSendTexLayerResponder() -{ - // mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below - if (mBakedUploadData) - { // ...but delete it in the case where uploadComplete() is never called - delete mBakedUploadData; - mBakedUploadData = NULL; - } -} - - -// Baked texture upload completed -void LLSendTexLayerResponder::uploadComplete(const LLSD& content) -{ - LLUUID item_id = mPostData["item_id"]; - - std::string result = content["state"]; - LLUUID new_id = content["new_asset"]; - - llinfos << "result: " << result << " new_id: " << new_id << llendl; - if (result == "complete" - && mBakedUploadData != NULL) - { // Invoke - LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE); - mBakedUploadData = NULL; // deleted in onTextureUploadComplete() - } - else - { // Invoke the original callback with an error result - LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); - mBakedUploadData = NULL; // deleted in onTextureUploadComplete() - } -} - -void LLSendTexLayerResponder::httpFailure(void) -{ - llinfos << "status: " << mStatus << " reason: " << mReason << llendl; - - // Invoke the original callback with an error result - LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); - mBakedUploadData = NULL; // deleted in onTextureUploadComplete() -} - LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, @@ -533,7 +474,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) if(!item) { llwarns << "Inventory item for " << mVFileID - << " is no longer in agent inventory." << llendl; + << " is no longer in agent inventory." << LL_ENDL; return; } @@ -544,7 +485,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) gInventory.notifyObservers(); llinfos << "Inventory item " << item->getName() << " saved into " - << content["new_asset"].asString() << llendl; + << content["new_asset"].asString() << LL_ENDL; LLInventoryType::EType inventory_type = new_item->getInventoryType(); switch(inventory_type) @@ -605,6 +546,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) { previewp->onUpdateSucceeded(); } + break; } case LLInventoryType::IT_WEARABLE: @@ -650,8 +592,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) case LLAssetType::AT_NOTECARD: { // Update the UI with the new asset. - LLPreviewNotecard* nc; - nc = (LLPreviewNotecard*)LLPreview::find(item_id); + LLPreviewNotecard* nc = (LLPreviewNotecard*)LLPreview::find(item_id); if (nc) { // *HACK: we have to delete the asset in the VFS so @@ -674,8 +615,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) { if (mQueueId.notNull()) { - LLFloaterCompileQueue* queue = - (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId); + LLFloaterCompileQueue* queue = (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId); if (NULL != queue) { queue->removeItemByItemID(item_id); @@ -724,7 +664,7 @@ public: { llwarns << "LLAssetUploadResponder called with nonexistant " - << "vfile_id " << vfile_id << llendl; + << "vfile_id " << vfile_id << LL_ENDL; mVFileID.setNull(); mAssetType = LLAssetType::AT_NONE; } @@ -1020,17 +960,15 @@ LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResp delete mImpl; } -void LLNewAgentInventoryVariablePriceResponder::httpFailure(void) +void LLNewAgentInventoryVariablePriceResponder::httpFailure() { - lldebugs - << "LLNewAgentInventoryVariablePrice::error " << mStatus - << " reason: " << mReason << llendl; + const LLSD& content = getContent(); + LL_WARNS("Upload") << dumpResponse() << LL_ENDL; - if ( mContent.has("error") ) - { static const std::string _ERROR = "error"; - - mImpl->onTransportError(mContent[_ERROR]); + if ( content.has(_ERROR) ) + { + mImpl->onTransportError(content[_ERROR]); } else { @@ -1038,8 +976,14 @@ void LLNewAgentInventoryVariablePriceResponder::httpFailure(void) } } -void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) +void LLNewAgentInventoryVariablePriceResponder::httpSuccess() { + const LLSD& content = getContent(); + if (!content.isMap()) + { + failureResult(HTTP_INTERNAL_ERROR_OTHER, "Malformed response contents", content); + return; + } // Parse out application level errors and the appropriate // responses for them static const std::string _ERROR = "error"; @@ -1053,13 +997,14 @@ void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) static const std::string _RSVP = "rsvp"; // Check for application level errors - if (mContent.has(_ERROR)) + if ( content.has(_ERROR) ) { - onApplicationLevelError(mContent[_ERROR]); + LL_WARNS("Upload") << dumpResponse() << LL_ENDL; + onApplicationLevelError(content[_ERROR]); return; } - std::string state = mContent[_STATE]; + std::string state = content[_STATE]; LLAssetType::EType asset_type = mImpl->getAssetType(); if (_COMPLETE == state) @@ -1068,11 +1013,11 @@ void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) if (mImpl->getFilename().empty()) { // rename the file in the VFS to the actual asset id - // llinfos << "Changing uploaded asset UUID to " << mContent["new_asset"].asUUID() << llendl; + // LL_INFOS() << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << LL_ENDL; gVFS->renameFile( mImpl->getVFileID(), asset_type, - mContent["new_asset"].asUUID(), + content["new_asset"].asUUID(), asset_type); } @@ -1083,8 +1028,8 @@ void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) mImpl->getFolderID(), mImpl->getItemName(), mImpl->getItemDescription(), - mContent, - mContent[_UPLOAD_PRICE].asInteger()); + content, + content[_UPLOAD_PRICE].asInteger()); // TODO* Add bulk (serial) uploading or add // a super class of this that does so @@ -1092,12 +1037,13 @@ void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) else if ( _CONFIRM_UPLOAD == state ) { showConfirmationDialog( - mContent[_UPLOAD_PRICE].asInteger(), - mContent[_RESOURCE_COST].asInteger(), - mContent[_RSVP].asString()); + content[_UPLOAD_PRICE].asInteger(), + content[_RESOURCE_COST].asInteger(), + content[_RSVP].asString()); } else { + LL_WARNS("Upload") << dumpResponse() << LL_ENDL; onApplicationLevelError(""); } } @@ -1170,3 +1116,4 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog( } } + diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index 2c2b87152..21787786f 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -36,10 +36,6 @@ #include "llhttpclient.h" #include "llinventory.h" -class AIHTTPTimeoutPolicy; -extern AIHTTPTimeoutPolicy assetUploadResponder_timeout; -extern AIHTTPTimeoutPolicy newAgentInventoryVariablePriceResponder_timeout; - void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type, LLInventoryType::EType inventory_type, const std::string inventory_type_string, @@ -53,6 +49,8 @@ void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type, // via capabilities class LLAssetUploadResponder : public LLHTTPClient::ResponderWithResult { +protected: + LOG_CLASS(LLAssetUploadResponder); public: LLAssetUploadResponder(const LLSD& post_data, const LLUUID& vfile_id, @@ -61,10 +59,12 @@ public: const std::string& file_name, LLAssetType::EType asset_type); ~LLAssetUploadResponder(); - /*virtual*/ void httpFailure(void); - /*virtual*/ void httpSuccess(void); - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return assetUploadResponder_timeout; } +protected: + virtual void httpFailure(); + virtual void httpSuccess(); + +public: virtual void uploadUpload(const LLSD& content); virtual void uploadComplete(const LLSD& content); virtual void uploadFailure(const LLSD& content); @@ -76,25 +76,24 @@ protected: std::string mFileName; }; +// TODO*: Remove this once deprecated class LLNewAgentInventoryResponder : public LLAssetUploadResponder { - void (*mCallBack)(bool, void*); - void* mUserData; + LOG_CLASS(LLNewAgentInventoryResponder); public: LLNewAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, - LLAssetType::EType asset_type, - void (*callback)(bool, void*) = NULL, - void* user_data = NULL); + LLAssetType::EType asset_type); LLNewAgentInventoryResponder( const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type); - /*virtual*/ void httpFailure(void); virtual void uploadComplete(const LLSD& content); virtual void uploadFailure(const LLSD& content); - /*virtual*/ char const* getName(void) const { return "LLNewAgentInventoryResponder"; } + /*virtual*/ char const* getName() const { return "LLNewAgentInventoryResponder"; } +protected: + virtual void httpFailure(); }; // A base class which goes through and performs some default @@ -104,6 +103,7 @@ public: class LLNewAgentInventoryVariablePriceResponder : public LLHTTPClient::ResponderWithResult { + LOG_CLASS(LLNewAgentInventoryVariablePriceResponder); public: LLNewAgentInventoryVariablePriceResponder( const LLUUID& vfile_id, @@ -116,10 +116,11 @@ public: const LLSD& inventory_info); virtual ~LLNewAgentInventoryVariablePriceResponder(); - /*virtual*/ void httpFailure(void); - /*virtual*/ void httpSuccess(void); - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return newAgentInventoryVariablePriceResponder_timeout; } +private: + /* virtual */ void httpFailure(); + /* virtual */ void httpSuccess(); +public: virtual void onApplicationLevelError( const LLSD& error); virtual void showConfirmationDialog( @@ -132,25 +133,6 @@ private: Impl* mImpl; }; -struct LLBakedUploadData; -class LLSendTexLayerResponder : public LLAssetUploadResponder -{ - LOG_CLASS(LLSendTexLayerResponder); -public: - LLSendTexLayerResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type, - LLBakedUploadData * baked_upload_data); - - ~LLSendTexLayerResponder(); - - /*virtual*/ void uploadComplete(const LLSD& content); - /*virtual*/ void httpFailure(void); - /*virtual*/ char const* getName(void) const { return "LLSendTexLayerResponder"; } - - LLBakedUploadData * mBakedUploadData; -}; - class LLUpdateAgentInventoryResponder : public LLAssetUploadResponder { public: @@ -161,7 +143,7 @@ public: const std::string& file_name, LLAssetType::EType asset_type); virtual void uploadComplete(const LLSD& content); - /*virtual*/ char const* getName(void) const { return "LLUpdateAgentInventoryResponder"; } + /*virtual*/ char const* getName() const { return "LLUpdateAgentInventoryResponder"; } }; class LLUpdateTaskInventoryResponder : public LLAssetUploadResponder @@ -179,7 +161,7 @@ public: LLAssetType::EType asset_type); virtual void uploadComplete(const LLSD& content); - /*virtual*/ char const* getName(void) const { return "LLUpdateTaskInventoryResponder"; } + /*virtual*/ char const* getName() const { return "LLUpdateTaskInventoryResponder"; } private: LLUUID mQueueId; diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 9d7e2c0be..29019118c 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -1426,7 +1426,7 @@ void LLSnapshotLivePreview::saveTexture() LLAssetStorage::LLStoreAssetCallback callback = &LLSnapshotLivePreview::saveTextureDone; S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); saveTextureUserData* user_data = new saveTextureUserData(this, sSnapshotIndex, gSavedSettings.getBOOL("TemporaryUpload")); - if (!upload_new_resource(tid, // tid + if (upload_new_resource(tid, // tid LLAssetType::AT_TEXTURE, "Snapshot : " + pos_string, "Taken by " + who_took_it + " at " + pos_string, @@ -1437,7 +1437,11 @@ void LLSnapshotLivePreview::saveTexture() LLFloaterPerms::getGroupPerms("Uploads"), // that is more permissive than other uploads LLFloaterPerms::getEveryonePerms("Uploads"), "Snapshot : " + pos_string, - callback, expected_upload_cost, user_data, &LLSnapshotLivePreview::saveTextureDone2)) + callback, expected_upload_cost, user_data)) + { + saveTextureDone2(true, user_data); + } + else { // Something went wrong. delete user_data; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 301a461f7..c6e2fdc86 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -1177,8 +1177,7 @@ bool upload_new_resource( const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, - void *userdata, - void (*callback2)(bool, void*)) + void *userdata) { if(gDisconnected) { @@ -1230,9 +1229,7 @@ bool upload_new_resource( new LLNewAgentInventoryResponder( body, uuid, - asset_type, - callback2, - userdata)); + asset_type)); } else { @@ -1294,17 +1291,16 @@ bool upload_new_resource( LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid) { - LLAssetID uuid; - if (gDisconnected) { - uuid.setNull(); - } - else - { - uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + LLAssetID rv; + + rv.setNull(); + return rv; } + LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + return uuid; } diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 65ff1a425..4eefa6a93 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -78,8 +78,7 @@ bool upload_new_resource(const LLTransactionID &tid, const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, - void *userdata, - void (*callback2)(bool, void*) = NULL); + void *userdata); // The default callback functions, called when 'callback' == NULL (for normal and temporary uploads). // user_data must be a LLResourceData allocated with new (or NULL). diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index cbf32eb43..f563c4062 100644 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp @@ -361,6 +361,51 @@ BOOL LLViewerTexLayerSetBuffer::requestUpdateImmediate() return result; } +class LLSendTexLayerResponder : public LLAssetUploadResponder +{ + LOG_CLASS(LLSendTexLayerResponder); +public: + LLSendTexLayerResponder(const LLSD& post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type, LLBakedUploadData * baked_upload_data) + : LLAssetUploadResponder(post_data, vfile_id, asset_type) + , mBakedUploadData(baked_upload_data) + {} + + ~LLSendTexLayerResponder() + { + // mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below + if (mBakedUploadData) + { // ...but delete it in the case where uploadComplete() is never called + delete mBakedUploadData; + mBakedUploadData = NULL; + } + } + + // Baked texture upload completed + /*virtual*/ void uploadComplete(const LLSD& content) + { + const std::string& result = content["state"]; + const LLUUID& new_id = content["new_asset"]; + + llinfos << "result: " << result << " new_id: " << new_id << llendl; + LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, (result == "complete" && mBakedUploadData) ? 0 : -1, LL_EXSTAT_NONE); + mBakedUploadData = NULL; // deleted in onTextureUploadComplete() + } + + /*virtual*/ void httpFailure() + { + llinfos << dumpResponse() << llendl; + + // Invoke the original callback with an error result + LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID::null, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); + mBakedUploadData = NULL; // deleted in onTextureUploadComplete() + } + + /*virtual*/ char const* getName() const { return "LLSendTexLayerResponder"; } + +private: + LLBakedUploadData* mBakedUploadData; +}; + // Create the baked texture, send it out to the server, then wait for it to come // back so we can switch to using it. void LLViewerTexLayerSetBuffer::doUpload() From 86ff77665cce05c32a384944c32ce2575c942560 Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Thu, 11 Sep 2014 19:45:15 -0400 Subject: [PATCH 13/15] Sync llviewerobjectbackup with Cool VL Viewer Note to Translators: -Adds translation work to floater_object_backup.xml -Adds ImportFailed, ExportAborted, and ConfirmAbortBackup to notifications.xml Turns LLViewerObjectBackup into an LLFloaterSingleton.. but eventually, this should probably be an instance tracker on the uuid of the object to export or something instead. --- indra/newview/llviewerobjectbackup.cpp | 752 +++++++++++------- indra/newview/llviewerobjectbackup.h | 151 ++-- indra/newview/llviewerobjectlist.cpp | 4 +- .../xui/en-us/floater_object_backup.xml | 16 +- .../skins/default/xui/en-us/notifications.xml | 33 +- 5 files changed, 591 insertions(+), 365 deletions(-) diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index a24a8b231..d4f3230c5 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -29,76 +29,60 @@ #include "llviewerprecompiledheaders.h" -// system library includes #include #include #include -// linden library includes -#include "indra_constants.h" -#include "llapr.h" #include "llcallbacklist.h" #include "lldir.h" #include "lleconomy.h" #include "llhttpclient.h" -#include "llimage.h" +#include "llinventorydefines.h" #include "llimagej2c.h" #include "lllfsthread.h" #include "llnotificationsutil.h" #include "llsdserialize.h" -#include "llsdutil.h" #include "llsdutil_math.h" #include "lltransactiontypes.h" -#include "llinventorydefines.h" +#include "lluictrlfactory.h" +#include "lluploaddialog.h" -// newview includes #include "llagent.h" #include "llappviewer.h" #include "llassetuploadresponders.h" -#include "statemachine/aifilepicker.h" -#include "llfloaterbvhpreview.h" -#include "llfloaterbuycurrency.h" -#include "llfloaterimagepreview.h" -#include "llfloaternamedesc.h" -#include "llfloatersnapshot.h" -#include "llinventorymodel.h" // gInventory #include "llinventoryfunctions.h" -#include "llresourcedata.h" +#include "llinventorymodel.h" // for gInventory #include "llmaterialmgr.h" #include "llselectmgr.h" -#include "llstatusbar.h" #include "lltexturecache.h" #include "lltoolplacer.h" -#include "lluictrlfactory.h" -#include "lluploaddialog.h" #include "llviewercontrol.h" #include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewermenu.h" +#include "lfsimfeaturehandler.h" #include "llviewerregion.h" -#include "llviewerstats.h" #include "llviewerwindow.h" -#include "hippogridmanager.h" -#include "lfsimfeaturehandler.h" - -#include "llviewerobjectbackup.h" - -LLObjectBackup* LLObjectBackup::sInstance = NULL; +#include "llviewerobjectbackup.h" // Note: these default textures are initialized with hard coded values to // prevent cheating. When not in SL, the user-configurable values are used // instead (see setDefaultTextures() below). -static LLUUID LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f"); -static LLUUID LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f"); -static LLUUID LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837"); -static LLUUID LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); -static LLUUID LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"); +LLUUID LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f"); +LLUUID LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f"); +LLUUID LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837"); +LLUUID LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); +LLUUID LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"); -class importResponder : public LLNewAgentInventoryResponder +class ImportObjectResponder: public LLNewAgentInventoryResponder { +protected: + LOG_CLASS(ImportObjectResponder); + public: - importResponder(const LLSD& post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type) + ImportObjectResponder(const LLSD& post_data, const LLUUID& vfile_id, + LLAssetType::EType asset_type) : LLNewAgentInventoryResponder(post_data, vfile_id, asset_type) { } @@ -106,10 +90,18 @@ public: //virtual virtual void uploadComplete(const LLSD& content) { - LL_DEBUGS("ObjectBackup") << "LLNewAgentInventoryResponder::result from capabilities" << LL_ENDL; + LLObjectBackup* self = LLObjectBackup::findInstance(); + if (!self) + { + llwarns << "Import aborted, LLObjectBackup instance gone !" + << llendl; + // remove the "Uploading..." message + LLUploadDialog::modalUploadFinished(); + return; + } LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); - LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); + LLInventoryType::EType inv_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); // Update L$ and ownership credit information // since it probably changed on the server @@ -117,18 +109,19 @@ public: asset_type == LLAssetType::AT_SOUND || asset_type == LLAssetType::AT_ANIMATION) { - gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); - gMessageSystem->nextBlockFast(_PREHASH_MoneyData); - gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MoneyBalanceRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); + msg->nextBlockFast(_PREHASH_MoneyData); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); gAgent.sendReliableMessage(); } // Actually add the upload to viewer inventory - LL_INFOS("ObjectBackup") << "Adding " << content["new_inventory_item"].asUUID() << " " - << content["new_asset"].asUUID() << " to inventory." << LL_ENDL; + llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " + << content["new_asset"].asUUID() << " to inventory." << llendl; if (mPostData["folder_id"].asUUID().notNull()) { LLPermissions perm; @@ -144,13 +137,12 @@ public: } 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(), + LLPointer item; + item = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), mPostData["folder_id"].asUUID(), perm, content["new_asset"].asUUID(), - asset_type, - inventory_type, + asset_type, inv_type, mPostData["name"].asString(), mPostData["description"].asString(), LLSaleInfo::DEFAULT, @@ -161,35 +153,43 @@ public: } else { - LL_WARNS("ObjectBackup") << "Can't find a folder to put it into" << LL_ENDL; + 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(); + self->updateMap(content["new_asset"].asUUID()); + self->uploadNextAsset(); } /*virtual*/ char const* getName(void) const { return "importResponder"; } }; -class CacheReadResponder : public LLTextureCache::ReadResponder +class BackupCacheReadResponder : public LLTextureCache::ReadResponder { +protected: + LOG_CLASS(BackupCacheReadResponder); + public: - CacheReadResponder(const LLUUID& id, LLImageFormatted* image) + BackupCacheReadResponder(const LLUUID& id, LLImageFormatted* image) : mFormattedImage(image), mID(id) { setImage(image); } - void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) + void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, + BOOL imagelocal) { + LLObjectBackup* self = LLObjectBackup::findInstance(); + if (!self) return; + if (imageformat == IMG_CODEC_TGA && mFormattedImage->getCodec() == IMG_CODEC_J2C) { - LL_WARNS("ObjectBackup") << "FAILED: texture " << mID << " is formatted as TGA. Not saving." << LL_ENDL; - LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_BAD_ENCODING; + llwarns << "FAILED: texture " << mID + << " is formatted as TGA. Not saving." << llendl; + self->mNonExportedTextures |= LLObjectBackup::TEXTURE_BAD_ENCODING; mFormattedImage = NULL; mImageSize = 0; return; @@ -197,8 +197,20 @@ public: if (mFormattedImage.notNull()) { - llassert_always(mFormattedImage->getCodec() == imageformat); - mFormattedImage->appendData(data, datasize); + if (mFormattedImage->getCodec() == imageformat) + { + mFormattedImage->appendData(data, datasize); + } + else + { + llwarns << "FAILED: texture " << mID + << " is formatted as " << mFormattedImage->getCodec() + << " while expecting " << imageformat + << ". Not saving." << llendl; + mFormattedImage = NULL; + mImageSize = 0; + return; + } } else { @@ -211,34 +223,42 @@ public: virtual void completed(bool success) { + LLObjectBackup* self = LLObjectBackup::findInstance(); + if (!self) + { + llwarns << "Export aborted, LLObjectBackup instance gone !" + << llendl; + return; + } + if (success && mFormattedImage.notNull() && mImageSize > 0) { - LL_INFOS("ObjectBackup") << "SUCCESS getting texture " << mID << LL_ENDL; + llinfos << "SUCCESS getting texture " << mID << llendl; std::string name; mID.toString(name); - name = LLObjectBackup::getInstance()->getfolder() + "//" + name; - LL_INFOS("ObjectBackup") << "Saving to " << name << LL_ENDL; + name = self->getFolder() + "//" + name; + llinfos << "Saving to " << name << llendl; if (!mFormattedImage->save(name)) { - LL_WARNS("ObjectBackup") << "FAILED to save texture " << mID << LL_ENDL; - LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_SAVED_FAILED; + llwarns << "FAILED to save texture " << mID << llendl; + self->mNonExportedTextures |= LLObjectBackup::TEXTURE_SAVED_FAILED; } } else { if (!success) { - LL_WARNS("ObjectBackup") << "FAILED to get texture " << mID << LL_ENDL; - LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_MISSING; + llwarns << "FAILED to get texture " << mID << llendl; + self->mNonExportedTextures |= LLObjectBackup::TEXTURE_MISSING; } if (mFormattedImage.isNull()) { - LL_WARNS("ObjectBackup") << "FAILED: NULL texture " << mID << LL_ENDL; - LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_IS_NULL; + llwarns << "FAILED: NULL texture " << mID << llendl; + self->mNonExportedTextures |= LLObjectBackup::TEXTURE_IS_NULL; } } - LLObjectBackup::getInstance()->mCheckNextTexture = true; + self->mCheckNextTexture = true; } private: @@ -246,62 +266,70 @@ private: LLUUID mID; }; -LLObjectBackup::LLObjectBackup() -: LLFloater(std::string("Object Backup Floater"), std::string("FloaterObjectBackuptRect"), LLStringUtil::null) +LLObjectBackup::LLObjectBackup(const LLSD&) +: mRunning(false), + mRetexture(false), + mTexturesList(), + mAssetMap(), + mCurrentAsset() { //buildFromFile("floater_object.xml"); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_object_backup.xml", NULL, false); - mRunning = false; - mTexturesList.clear(); - mAssetMap.clear(); - mCurrentAsset.setNull(); - mRetexture = false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLObjectBackup* LLObjectBackup::getInstance() -{ - if (!sInstance) - { - sInstance = new LLObjectBackup(); - } - return sInstance; + LLUICtrlFactory::getInstance()->buildFloater(this, + "floater_object_backup.xml", + NULL, false); // Don't open } +//virtual LLObjectBackup::~LLObjectBackup() { - // save position of floater - gSavedSettings.setRect("FloaterObjectBackuptRect", getRect()); - sInstance = NULL; + // Just in case we got closed unexpectedly... + if (gIdleCallbacks.containsFunction(exportWorker)) + { + gIdleCallbacks.deleteFunction(exportWorker); + } } -void LLObjectBackup::show(bool exporting) +//static +bool LLObjectBackup::confirmCloseCallback(const LLSD& notification, + const LLSD& response) { - // set the title - if (exporting) + if (LLNotification::getSelectedOption(notification, response) == 0) { - setTitle("Object export"); + LLObjectBackup* self = findInstance(); + if (self) + { + self->destroy(); + } + } + return false; +} + +//virtual +void LLObjectBackup::onClose(bool app_quitting) +{ + // Do not destroy the floater on user close action to avoid getting things + // messed up during import/export. + if (app_quitting) + { + destroy(); } else { - setTitle("Object import"); + LLNotificationsUtil::add("ConfirmAbortBackup", LLSD(), LLSD(), + confirmCloseCallback); } - mCurObject = 1; - mCurPrim = 0; - mObjects = 0; - mPrims = 0; - mRezCount = 0; - - // make floater appear - setVisibleAndFrontmost(); } -void LLObjectBackup::onClose(bool app_quitting) +void LLObjectBackup::showFloater(bool exporting) { - setVisible(false); - // HACK for fast XML iteration replace with: - // destroy(); + // Set the title + setTitle(getString(exporting ? "export" : "import")); + + mCurObject = 1; + mCurPrim = mObjects = mPrims = mRezCount = 0; + + // Make the floater pop up + setVisibleAndFrontmost(); } void LLObjectBackup::updateExportNumbers() @@ -322,7 +350,8 @@ void LLObjectBackup::updateImportNumbers() if (mRetexture) { - sstr << " Textures uploads remaining : " << mTexturesList.size() << "\n"; + sstr << " Textures uploads remaining : " << mTexturesList.size() + << "\n"; ctrl->setValue(LLSD("Text") = sstr.str()); } else @@ -392,6 +421,7 @@ void LLObjectBackup::setDefaultTextures() } } +//static bool LLObjectBackup::validatePerms(const LLPermissions* item_permissions) { return item_permissions->allowExportBy(gAgentID, LFSimFeatureHandler::instance().exportPolicy()); @@ -406,18 +436,16 @@ bool LLObjectBackup::validatePerms(const LLPermissions* item_permissions) // 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(const LLUUID& asset_id) -{ - if (!gHippoGridManager->getConnectedGrid()->isSecondLife()) - { - // If we are not in Second Life, don't bother. - return asset_id; - } - if (mBadPermsTexturesList.count(asset_id)) +//static +bool LLObjectBackup::validateTexturePerms(const LLUUID& asset_id) +{ + if (LFSimFeatureHandler::instance().exportPolicy() == ep_full_perm) { - // We already checked it and know it's bad... - return LL_TEXTURE_PLYWOOD; + // If we are not in Second Life and we don't have export-permission + // support, don't bother and unconditionally accept the texture export + // (legacy behaviour). + return true; } if (asset_id == LL_TEXTURE_PLYWOOD || @@ -427,7 +455,7 @@ LLUUID LLObjectBackup::validateTextureID(const LLUUID& asset_id) asset_id == LL_TEXTURE_MEDIA) { // Allow to export a few default SL textures. - return asset_id; + return true; } LLViewerInventoryCategory::cat_array_t cats; @@ -444,32 +472,94 @@ LLUUID LLObjectBackup::validateTextureID(const LLUUID& asset_id) const LLPermissions item_permissions = items[i]->getPermissions(); if (validatePerms(&item_permissions)) { - return asset_id; + return true; } } } + return false; +} + +LLUUID LLObjectBackup::validateTextureID(const LLUUID& asset_id) +{ + if (mBadPermsTexturesList.count(asset_id)) + { + // We already checked it and know it's bad... + return LL_TEXTURE_PLYWOOD; + } + else if (asset_id.isNull() || validateTexturePerms(asset_id)) + { + return asset_id; + } + else { mBadPermsTexturesList.insert(asset_id); // Cache bad texture ID mNonExportedTextures |= TEXTURE_BAD_PERM; - LL_WARNS("ObjectBackup") << "Bad permissions for texture ID: " << asset_id - << " - Texture will not be exported." << LL_ENDL; + llwarns << "Bad permissions for texture ID: " << asset_id + << " - Texture will not be exported." << llendl; return LL_TEXTURE_PLYWOOD; } } +//static +bool LLObjectBackup::validateNode(LLSelectNode* node) +{ + LLPermissions* perms = node->mPermissions; + if (!perms || !validatePerms(perms)) + { + return false; + } + + // Additionally check if this is a sculpt or a mesh object and if yes, if + // we have export permission on the sclupt texture or the mesh object. + LLViewerObject* obj = node->getObject(); + if (!obj) // Paranoia + { + return false; + } + else if (obj->isSculpted()) + { + if (obj->isMesh()) + { + return false; // We can't export mesh from here, anyway. + } + else + { + LLSculptParams* params; + params = (LLSculptParams*)obj->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLUUID sculpt_id = params->getSculptTexture(); + return validateTexturePerms(sculpt_id); + } + } + else + { + return true; + } +} //---------------------------------------------------------------------------// +//static void LLObjectBackup::exportWorker(void *userdata) { - getInstance()->updateExportNumbers(); + LLObjectBackup* self = findInstance(); + if (!self) + { + gIdleCallbacks.deleteFunction(exportWorker); + llwarns << "Export process aborted. LLObjectBackup instance gone !" + << llendl; + LLNotifications::instance().add("ExportAborted"); + return; + } - switch (getInstance()->mExportState) + self->updateExportNumbers(); + + switch (self->mExportState) { case EXPORT_INIT: { - getInstance()->show(true); + self->showFloater(true); + LLSelectMgr::getInstance()->getSelection()->ref(); // Fall through to EXPORT_CHECK_PERMS } case EXPORT_CHECK_PERMS: @@ -478,16 +568,17 @@ void LLObjectBackup::exportWorker(void *userdata) { virtual bool apply(LLSelectNode* node) { - return getInstance()->validatePerms(node->mPermissions); + return LLObjectBackup::validateNode(node); } } func; - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + LLViewerObject* object; + object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (object) { if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) { - getInstance()->mExportState = EXPORT_FETCH_PHYSICS; + self->mExportState = EXPORT_FETCH_PHYSICS; } else { @@ -501,21 +592,21 @@ void LLObjectBackup::exportWorker(void *userdata) if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func2, false)) { - LL_WARNS("ObjectBackup") << "Incorrect permission to export" << LL_ENDL; - getInstance()->mExportState = EXPORT_FAILED; + llwarns << "Incorrect permission to export" << llendl; + self->mExportState = EXPORT_FAILED; LLSelectMgr::getInstance()->getSelection()->unref(); } else { LL_DEBUGS("ObjectBackup") << "Nodes permissions not yet received, delaying..." << LL_ENDL; - getInstance()->mExportState = EXPORT_CHECK_PERMS; + self->mExportState = EXPORT_CHECK_PERMS; } } } else { - LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED; + self->mExportState = EXPORT_ABORTED; LLSelectMgr::getInstance()->getSelection()->unref(); } break; @@ -525,9 +616,9 @@ void LLObjectBackup::exportWorker(void *userdata) { // Don't bother to try and fetch the extra physics flags if we // don't have sim support for them... - if (!getInstance()->mGotExtraPhysics) + if (!self->mGotExtraPhysics) { - getInstance()->mExportState = EXPORT_STRUCTURE; + self->mExportState = EXPORT_STRUCTURE; break; } @@ -545,7 +636,7 @@ void LLObjectBackup::exportWorker(void *userdata) { if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) { - getInstance()->mExportState = EXPORT_STRUCTURE; + self->mExportState = EXPORT_STRUCTURE; } else { @@ -555,7 +646,7 @@ void LLObjectBackup::exportWorker(void *userdata) } else { - getInstance()->mExportState = EXPORT_FAILED; + self->mExportState = EXPORT_ABORTED; LLSelectMgr::getInstance()->getSelection()->unref(); } break; @@ -571,7 +662,9 @@ void LLObjectBackup::exportWorker(void *userdata) 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, is_attachment); + LLObjectBackup* self = findInstance(); + LLSD prim_llsd = self->primsToLLSD(children, + is_attachment); LLSD stuff; if (is_attachment) { @@ -584,77 +677,88 @@ void LLObjectBackup::exportWorker(void *userdata) stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); } stuff["group_body"] = prim_llsd; - getInstance()->mLLSD["data"].append(stuff); + self->mLLSD["data"].append(stuff); return true; } } func; - getInstance()->mExportState = EXPORT_LLSD; - LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); + LLViewerObject* object; + object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (object) + { + self->mExportState = EXPORT_LLSD; + LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); + } + else + { + self->mExportState = EXPORT_ABORTED; + } LLSelectMgr::getInstance()->getSelection()->unref(); break; } case EXPORT_TEXTURES: { - if (!getInstance()->mCheckNextTexture) + if (!self->mCheckNextTexture) { // The texture is being fetched. Wait till next idle callback. return; } - if (getInstance()->mTexturesList.empty()) + if (self->mTexturesList.empty()) { - getInstance()->mExportState = EXPORT_DONE; + self->mExportState = EXPORT_DONE; return; } // Ok, we got work to do... - getInstance()->mCheckNextTexture= false; - getInstance()->exportNextTexture(); + self->mCheckNextTexture = false; + self->exportNextTexture(); break; } case EXPORT_LLSD: { // Create a file stream and write to it - llofstream export_file(getInstance()->mFileName); - LLSDSerialize::toPrettyXML(getInstance()->mLLSD, export_file); + llofstream export_file(self->mFileName); + LLSDSerialize::toPrettyXML(self->mLLSD, export_file); export_file.close(); - getInstance()->mCheckNextTexture = true; - getInstance()->mExportState = EXPORT_TEXTURES; + self->mCheckNextTexture = true; + self->mExportState = EXPORT_TEXTURES; break; } case EXPORT_DONE: { gIdleCallbacks.deleteFunction(exportWorker); - if (LLObjectBackup::getInstance()->mNonExportedTextures == LLObjectBackup::TEXTURE_OK) + if (self->mNonExportedTextures == LLObjectBackup::TEXTURE_OK) { - LL_INFOS("ObjectBackup") << "Export successful and complete." << LL_ENDL; + llinfos << "Export successful and complete." << llendl; LLNotificationsUtil::add("ExportSuccessful"); } else { - LL_INFOS("ObjectBackup") << "Export successful but incomplete: some texture(s) not saved." << LL_ENDL; + llinfos << "Export successful but incomplete: some texture(s) not saved." + << llendl; std::string reason; - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_PERM) + U32 error_bits_map = self->mNonExportedTextures; + if (error_bits_map & LLObjectBackup::TEXTURE_BAD_PERM) { reason += "\nBad permissions/creator."; } - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_MISSING) + if (error_bits_map & LLObjectBackup::TEXTURE_MISSING) { reason += "\nMissing texture (retrying after full rezzing might work)."; } - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_ENCODING) + if (error_bits_map & LLObjectBackup::TEXTURE_BAD_ENCODING) { reason += "\nBad texture encoding."; } - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_IS_NULL) + if (error_bits_map & LLObjectBackup::TEXTURE_IS_NULL) { reason += "\nNull texture."; } - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_SAVED_FAILED) + if (error_bits_map & LLObjectBackup::TEXTURE_SAVED_FAILED) { reason += "\nCould not write to disk."; } @@ -662,22 +766,32 @@ void LLObjectBackup::exportWorker(void *userdata) args["REASON"] = reason; LLNotificationsUtil::add("ExportPartial", args); } - getInstance()->close(); + self->destroy(); break; } case EXPORT_FAILED: { gIdleCallbacks.deleteFunction(exportWorker); - LL_WARNS("ObjectBackup") << "Export process aborted." << LL_ENDL; + llwarns << "Export process failed." << llendl; LLNotificationsUtil::add("ExportFailed"); - LLObjectBackup::getInstance()->close(); + self->destroy(); + break; + } + + case EXPORT_ABORTED: + { + gIdleCallbacks.deleteFunction(exportWorker); + llwarns << "Export process aborted." << llendl; + LLNotificationsUtil::add("ExportAborted"); + self->destroy(); break; } } } -LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool is_attachment) +LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, + bool is_attachment) { LLViewerObject* object; LLSD llsd; @@ -690,7 +804,7 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i object = (*i); LLUUID id = object->getID(); - LL_INFOS("ObjectBackup") << "Exporting prim " << object->getID().asString() << LL_ENDL; + 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 @@ -753,27 +867,32 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i prim_llsd["volume"] = params.asLLSD(); // Extra paramsb6fab961-af18-77f8-cf08-f021377a7244 + if (object->isFlexible()) { // Flexible - LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); + LLFlexibleObjectData* flex; + 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); + LLLightParams* light; + light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); prim_llsd["light"] = light->asLLSD(); } if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) { // Light image - LLLightImageParams* light_param = (LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + LLLightImageParams* light_param; + light_param = (LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); t_id = validateTextureID(light_param->getLightTexture()); if (mTexturesList.count(t_id) == 0) { - LL_INFOS("ObjectBackup") << "Found a light texture, adding to list " << t_id << LL_ENDL; + llinfos << "Found a light texture, adding to list " << t_id + << llendl; mTexturesList.insert(t_id); } prim_llsd["light_texture"] = light_param->asLLSD(); @@ -782,7 +901,8 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) { // Sculpt - LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLSculptParams* sculpt; + sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); prim_llsd["sculpt"] = sculpt->asLLSD(); if ((sculpt->getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { @@ -791,14 +911,16 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i { if (mTexturesList.count(sculpt_texture) == 0) { - LL_INFOS("ObjectBackup") << "Found a sculpt texture, adding to list " << sculpt_texture << LL_ENDL; + llinfos << "Found a sculpt texture, adding to list " + << sculpt_texture << llendl; mTexturesList.insert(sculpt_texture); } } else { - LL_WARNS("ObjectBackup") << "Incorrect permission to export a sculpt texture." << LL_ENDL; - getInstance()->mExportState = EXPORT_FAILED; + llwarns << "Incorrect permission to export a sculpt texture." + << llendl; + mExportState = EXPORT_FAILED; } } } @@ -819,12 +941,8 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i this_te_llsd = te->asLLSD(); this_te_llsd["imageid"] = t_id; te_llsd.append(this_te_llsd); - // Do not export Linden textures even though they don't taint creation. - if (t_id != LL_TEXTURE_PLYWOOD && - t_id != LL_TEXTURE_BLANK && - t_id != LL_TEXTURE_TRANSPARENT && - t_id != LL_TEXTURE_INVISIBLE && - t_id != LL_TEXTURE_MEDIA) + // Do not export non-existent default textures + if (t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE) { if (mTexturesList.count(t_id) == 0) { @@ -862,8 +980,9 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i prim_llsd["materials"] = te_mat_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 + // 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; } @@ -882,7 +1001,7 @@ void LLObjectBackup::exportNextTexture() if (mTexturesList.empty()) { mCheckNextTexture = true; - LL_INFOS("ObjectBackup") << "Finished exporting textures." << LL_ENDL; + llinfos << "Finished exporting textures." << llendl; return; } if (iter == mTexturesList.end()) @@ -929,7 +1048,7 @@ void LLObjectBackup::exportNextTexture() } else { - LL_WARNS("ObjectBackup") << "We *DON'T* have the texture " << id.asString() << LL_ENDL; + llwarns << "We *DON'T* have the texture " << id << llendl; mNonExportedTextures |= TEXTURE_MISSING; mTexturesList.erase(id); } @@ -937,10 +1056,20 @@ void LLObjectBackup::exportNextTexture() mTexturesList.erase(id); - LL_INFOS("ObjectBackup") << "Requesting texture " << id << LL_ENDL; + llinfos << "Requesting texture " << id << " from cache." << llendl; LLImageJ2C* mFormattedImage = new LLImageJ2C; - CacheReadResponder* responder = new CacheReadResponder(id, mFormattedImage); - LLAppViewer::getTextureCache()->readFromCache(id, LLWorkerThread::PRIORITY_HIGH, 0, 999999, responder); + BackupCacheReadResponder* responder; + responder = new BackupCacheReadResponder(id, mFormattedImage); + LLAppViewer::getTextureCache()->readFromCache(id, + LLWorkerThread::PRIORITY_HIGH, + 0, 999999, responder); +} + + +bool is_default_texture(const LLUUID& id) +{ + return id.isNull() || id == LL_TEXTURE_PLYWOOD || id == LL_TEXTURE_BLANK || + id == LL_TEXTURE_INVISIBLE; } void LLObjectBackup::importObject(bool upload) @@ -949,7 +1078,7 @@ void LLObjectBackup::importObject(bool upload) mTexturesList.clear(); mAssetMap.clear(); mCurrentAsset.setNull(); - + mGotExtraPhysics = !gAgent.getRegion()->getCapability("GetObjectPhysicsData").empty(); setDefaultTextures(); @@ -975,18 +1104,19 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) import_file.close(); if (!mLLSD.has("data")) { - LLNotificationsUtil::add("InvalidObjectParams"); - close(); + LLNotificationsUtil::add("ImportFailed"); + destroy(); return; } - show(false); + showFloater(false); mAgentPos = gAgent.getPositionAgent(); mAgentRot = LLQuaternion(gAgent.getAtAxis(), gAgent.getLeftAxis(), gAgent.getUpAxis()); // Get the texture map + mCurObject = 1; mCurPrim = 1; mObjects = mLLSD["data"].size(); @@ -1014,14 +1144,31 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) LLUUID orig = sculpt.getSculptTexture(); if (mTexturesList.count(orig) == 0) { - LL_INFOS("ObjectBackup") << "Found a new SCULPT texture to upload " << orig << LL_ENDL; + llinfos << "Found a new SCULPT texture to upload " + << orig << llendl; mTexturesList.insert(orig); } } } - LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] : prim_llsd["texture"]; // Firestorm's format uses singular "texture" + if (prim_llsd.has("light_texture")) + { + LLLightImageParams lightimg; + lightimg.fromLLSD(prim_llsd["light_texture"]); + LLUUID t_id = lightimg.getLightTexture(); + if (!is_default_texture(t_id) && + mTexturesList.count(t_id) == 0) + { + llinfos << "Found a new light texture to upload: " << t_id + << llendl; + mTexturesList.insert(t_id); + } + } + // Check both for "textures" and "texture" since the second (buggy) + // case has already been seen in some exported prims XML files... + LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] + : prim_llsd["texture"]; for (LLSD::array_iterator it = te_llsd.beginArray(); it != te_llsd.endArray(); ++it) { @@ -1030,14 +1177,12 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) te.fromLLSD(the_te); LLUUID t_id = te.getID(); - // Do not upload the default textures - if (t_id != LL_TEXTURE_PLYWOOD && t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE) // Do not upload the default textures + if (!is_default_texture(t_id) && + mTexturesList.count(t_id) == 0) { - if (mTexturesList.count(t_id) == 0) - { - LL_INFOS("ObjectBackup") << "Found a new texture to upload: "<< t_id << LL_ENDL; + llinfos << "Found a new texture to upload: " << t_id + << llendl; mTexturesList.insert(t_id); - } } } @@ -1052,29 +1197,21 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) mat.fromLLSD(the_mat); LLUUID t_id = mat.getNormalID(); - if (t_id.notNull() && t_id != LL_TEXTURE_PLYWOOD && - t_id != LL_TEXTURE_BLANK && - t_id != LL_TEXTURE_INVISIBLE) + if (!is_default_texture(t_id) && + mTexturesList.count(t_id) == 0) { - if (mTexturesList.count(t_id) == 0) - { - LL_INFOS("ObjectBackup") << "Found a new normal map to upload: " - << t_id << LL_ENDL; - mTexturesList.insert(t_id); - } + llinfos << "Found a new normal map to upload: " + << t_id << llendl; + mTexturesList.insert(t_id); } t_id = mat.getSpecularID(); - if (t_id.notNull() && t_id != LL_TEXTURE_PLYWOOD && - t_id != LL_TEXTURE_BLANK && - t_id != LL_TEXTURE_INVISIBLE) + if (!is_default_texture(t_id) && + mTexturesList.count(t_id) == 0) { - if (mTexturesList.count(t_id) == 0) - { - LL_INFOS("ObjectBackup") << "Found a new specular map to upload: " - << t_id << LL_ENDL; - mTexturesList.insert(t_id); - } + llinfos << "Found a new specular map to upload: " + << t_id << llendl; + mTexturesList.insert(t_id); } } } @@ -1107,9 +1244,9 @@ void LLObjectBackup::rezAgentOffset(LLVector3 offset) void LLObjectBackup::importFirstObject() { mRunning = true; - show(false); + showFloater(false); mGroupPrimImportIter = mLLSD["data"].beginArray(); - mRootRootPos = (*mGroupPrimImportIter)["root_position"]; + mRootRootPos = LLVector3((*mGroupPrimImportIter)["root_position"]); mObjects = mLLSD["data"].size(); mCurObject = 1; importNextObject(); @@ -1127,7 +1264,7 @@ void LLObjectBackup::importNextObject() mPrims = mThisGroup.size(); updateImportNumbers(); - LLVector3 lgpos = (*mGroupPrimImportIter)["root_position"]; + LLVector3 lgpos = LLVector3((*mGroupPrimImportIter)["root_position"]); mGroupOffset = lgpos - mRootRootPos; mRootPos = offsetAgent(LLVector3(2.0, 0.0, 0.0)); mRootRot = ll_quaternion_from_sd((*mGroupPrimImportIter)["root_rotation"]); @@ -1168,7 +1305,7 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) if (prim_llsd.has("parent")) { //we are not the root node. - LLVector3 pos = prim_llsd["position"]; + LLVector3 pos = LLVector3(prim_llsd["position"]); LLQuaternion rot = ll_quaternion_from_sd(prim_llsd["rotation"]); object->setPositionRegion(pos * mRootRot + mRootPos + mGroupOffset); object->setRotation(rot * mRootRot); @@ -1180,11 +1317,11 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) object->setRotation(rot); } - object->setScale(prim_llsd["scale"]); + object->setScale(LLVector3(prim_llsd["scale"])); if (prim_llsd.has("flags")) { - U32 flags(prim_llsd["flags"].asInteger()); + U32 flags = (U32)prim_llsd["flags"].asInteger(); object->setFlags(flags, true); } else // Kept for backward compatibility @@ -1228,12 +1365,12 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLSculptParams sculpt; sculpt.fromLLSD(prim_llsd["sculpt"]); - // TODO: check if map is valid and only set texture if map is valid and changes - - if (mAssetMap.count(sculpt.getSculptTexture())) + // TODO: check if map is valid and only set texture if map is valid and + // changes + LLUUID t_id = sculpt.getSculptTexture(); + if (mAssetMap.count(t_id)) { - LLUUID replacement = mAssetMap[sculpt.getSculptTexture()]; - sculpt.setSculptTexture(replacement); + sculpt.setSculptTexture(mAssetMap[t_id]); } object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt, true); @@ -1250,7 +1387,13 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) // Light image LLLightImageParams lightimg; lightimg.fromLLSD(prim_llsd["light_texture"]); - object->setParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE, lightimg, true); + LLUUID t_id = lightimg.getLightTexture(); + if (mAssetMap.count(t_id)) + { + lightimg.setLightTexture(mAssetMap[t_id]); + } + object->setParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE, lightimg, + true); } if (prim_llsd.has("flexible")) @@ -1261,8 +1404,11 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) } // Textures - LL_INFOS("ObjectBackup") << "Processing textures for prim" << id << LL_ENDL; - LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] : prim_llsd["texture"]; // Firestorm's format uses singular "texture" + // Check both for "textures" and "texture" since the second (buggy) case + // has already been seen in some exported prims XML files... + llinfos << "Processing textures for prim" << id << llendl; + LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] + : prim_llsd["texture"]; U8 i = 0; for (LLSD::array_iterator it = te_llsd.beginArray(); it != te_llsd.endArray(); ++it) @@ -1273,18 +1419,17 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLUUID t_id = te.getID(); if (mAssetMap.count(t_id)) { - LLUUID replacement = mAssetMap[t_id]; - te.setID(replacement); + te.setID(mAssetMap[t_id]); } object->setTE(i++, te); } - LL_INFOS("ObjectBackup") << "Textures done !" << LL_ENDL; + llinfos << "Textures done !" << llendl; // Materials if (prim_llsd.has("materials")) { - LL_INFOS("ObjectBackup") << "Processing materials for prim " << id << LL_ENDL; + llinfos << "Processing materials for prim " << id << llendl; te_llsd = prim_llsd["materials"]; i = 0; for (LLSD::array_iterator it = te_llsd.beginArray(); @@ -1296,20 +1441,18 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLUUID t_id = mat->getNormalID(); if (id.notNull() && mAssetMap.count(t_id)) { - LLUUID replacement = mAssetMap[t_id]; - mat->setNormalID(replacement); + mat->setNormalID(mAssetMap[t_id]); } t_id = mat->getSpecularID(); if (id.notNull() && mAssetMap.count(t_id)) { - LLUUID replacement = mAssetMap[t_id]; - mat->setSpecularID(replacement); + mat->setSpecularID(mAssetMap[t_id]); } LLMaterialMgr::getInstance()->put(id, i++, *mat); } - LL_INFOS("ObjectBackup") << "Materials done !" << LL_ENDL; + llinfos << "Materials done !" << llendl; } object->sendRotationUpdate(); @@ -1320,107 +1463,110 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLSelectMgr::getInstance()->deselectAll(); } -// This is fired when the update packet is processed so we know the prim settings have stuck +// This is fired when the update packet is processed so we know the prim +// settings have stuck +//static void LLObjectBackup::primUpdate(LLViewerObject* object) { - if (!mRunning || (object != NULL && object->mID != mExpectingUpdate)) + LLObjectBackup* self = findInstance(); + if (!object || !self || !self->mRunning || + object->mID != self->mExpectingUpdate) { return; } - ++mCurPrim; - updateImportNumbers(); - ++mPrimImportIter; + ++self->mCurPrim; + self->updateImportNumbers(); + ++self->mPrimImportIter; - LLUUID x; - mExpectingUpdate = x.null; + self->mExpectingUpdate.setNull(); - if (mPrimImportIter == mThisGroup.endMap()) + if (self->mPrimImportIter == self->mThisGroup.endMap()) { - LL_INFOS("ObjectBackup") << "Trying to link" << LL_ENDL; + llinfos << "Trying to link..." << llendl; - if (mToSelect.size() > 1) + if (self->mToSelect.size() > 1) { - std::reverse(mToSelect.begin(), mToSelect.end()); + std::reverse(self->mToSelect.begin(), self->mToSelect.end()); // Now link LLSelectMgr::getInstance()->deselectAll(); - LLSelectMgr::getInstance()->selectObjectAndFamily(mToSelect, true); + LLSelectMgr::getInstance()->selectObjectAndFamily(self->mToSelect, true); LLSelectMgr::getInstance()->sendLink(); - LLViewerObject* root = mToSelect.back(); - root->setRotation(mRootRot); + LLViewerObject* root = self->mToSelect.back(); + root->setRotation(self->mRootRot); } - ++mCurObject; - ++mGroupPrimImportIter; - if (mGroupPrimImportIter != mLLSD["data"].endArray()) + ++self->mCurObject; + ++self->mGroupPrimImportIter; + if (self->mGroupPrimImportIter != self->mLLSD["data"].endArray()) { - importNextObject(); + self->importNextObject(); return; } - mRunning = false; - close(); + self->mRunning = false; + self->destroy(); return; } - LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; + LLSD prim_llsd = self->mThisGroup[self->mPrimImportIter->first]; - if (mToSelect.empty()) + if (self->mToSelect.empty()) { - LL_WARNS("ObjectBackup") << "error: ran out of objects to mod." << LL_ENDL; - mRunning = false; - close(); + llwarns << "error: ran out of objects to mod." << llendl; + self->mRunning = false; + self->destroy(); return; } - if (mPrimImportIter != mThisGroup.endMap()) + if (self->mPrimImportIter != self->mThisGroup.endMap()) { //rezAgentOffset(LLVector3(1.0, 0.0, 0.0)); - LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; - ++mProcessIter; - xmlToPrim(prim_llsd, *mProcessIter); + LLSD prim_llsd =self-> mThisGroup[self->mPrimImportIter->first]; + ++self->mProcessIter; + self->xmlToPrim(prim_llsd, *(self->mProcessIter)); } } // Callback when we rez a new object when the importer is running. -bool LLObjectBackup::newPrim(LLViewerObject* pobject) +//static +void LLObjectBackup::newPrim(LLViewerObject* object) { - if (mRunning) + LLObjectBackup* self = findInstance(); + if (!object || !self || !self->mRunning) return; + + ++self->mRezCount; + self->mToSelect.push_back(object); + self->updateImportNumbers(); + ++self->mPrimImportIter; + + object->setPosition(self->offsetAgent(LLVector3(0.0, 1.0, 0.0))); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); + + if (self->mPrimImportIter != self->mThisGroup.endMap()) { - ++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 - { - LL_INFOS("ObjectBackup") << "All prims rezzed, moving to build stage" << LL_ENDL; - // 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); - } + self->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(); + self->mPrimImportIter = self->mThisGroup.beginMap(); + LLSD prim_llsd = self->mThisGroup[self->mPrimImportIter->first]; + self->mProcessIter = self->mToSelect.begin(); + self->xmlToPrim(prim_llsd, *(self->mProcessIter)); } - return true; } void LLObjectBackup::updateMap(LLUUID uploaded_asset) { if (mCurrentAsset.notNull()) { - LL_INFOS("ObjectBackup") << "Mapping " << mCurrentAsset << " to " << uploaded_asset << LL_ENDL; - + llinfos << "Mapping " << mCurrentAsset << " to " << uploaded_asset + << llendl; mAssetMap[mCurrentAsset] = uploaded_asset; } } @@ -1445,8 +1591,7 @@ void myupload_new_resource(const LLTransactionID &tid, 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); + std::string upload_message = "Uploading texture:\n\n" + display_name; LLUploadDialog::modalUploadDialog(upload_message); std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); @@ -1463,12 +1608,15 @@ void myupload_new_resource(const LLTransactionID &tid, std::ostringstream llsdxml; LLSDSerialize::toXML(body, llsdxml); - LL_DEBUGS("ObjectBackup") << "posting body to capability: " << llsdxml.str() << LL_ENDL; - LLHTTPClient::post(url, body, new importResponder(body, uuid, asset_type)); + LL_DEBUGS("ObjectBackup") << "posting body to capability: " + << llsdxml.str() << LL_ENDL; + LLHTTPClient::post(url, body, + new ImportObjectResponder(body, uuid, asset_type)); } else { - LL_INFOS("ObjectBackup") << "NewAgentInventory capability not found. Can't upload !" << LL_ENDL; + llinfos << "NewAgentInventory capability not found. Can't upload !" + << llendl; } } @@ -1476,7 +1624,7 @@ void LLObjectBackup::uploadNextAsset() { if (mTexturesList.empty()) { - LL_INFOS("ObjectBackup") << "Texture list is empty, moving to rez stage." << LL_ENDL; + llinfos << "Texture list is empty, moving to rez stage." << llendl; mCurrentAsset.setNull(); importFirstObject(); return; @@ -1488,7 +1636,7 @@ void LLObjectBackup::uploadNextAsset() LLUUID id = *iter; mTexturesList.erase(iter); - LL_INFOS("ObjectBackup") << "Got texture ID " << id << ": trying to upload..." << LL_ENDL; + llinfos << "Got texture ID " << id << ": trying to upload..." << llendl; mCurrentAsset = id; std::string struid; @@ -1517,7 +1665,7 @@ void LLObjectBackup::uploadNextAsset() } else { - LL_WARNS("ObjectBackup") << "Unable to access output file " << filename << LL_ENDL; + llwarns << "Unable to access output file " << filename << llendl; uploadNextAsset(); return; } @@ -1525,5 +1673,5 @@ void LLObjectBackup::uploadNextAsset() myupload_new_resource(tid, LLAssetType::AT_TEXTURE, struid, struid, 0, LLFolderType::FT_TEXTURE, LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), - 0x0, "Uploaded texture", NULL, NULL); + 0x0, struid, NULL, NULL); } diff --git a/indra/newview/llviewerobjectbackup.h b/indra/newview/llviewerobjectbackup.h index 2b29d91fd..2b2283dff 100644 --- a/indra/newview/llviewerobjectbackup.h +++ b/indra/newview/llviewerobjectbackup.h @@ -30,10 +30,22 @@ #ifndef LL_LLVIEWEROBJECTBACKUP_H #define LL_LLVIEWEROBJECTBACKUP_H +#include +#include +#include + #include "boost/unordered_map.hpp" #include "boost/unordered_set.hpp" +#include "llfloater.h" +#include "statemachine/aifilepicker.h" +#include "lluuid.h" + #include "llviewerinventory.h" +#include "llviewerobject.h" + +class LLSelectNode; +class LLViewerObject; enum export_states { EXPORT_INIT, @@ -43,24 +55,27 @@ enum export_states { EXPORT_TEXTURES, EXPORT_LLSD, EXPORT_DONE, - EXPORT_FAILED + EXPORT_FAILED, + EXPORT_ABORTED }; -class LLObjectBackup : public LLFloater +class LLObjectBackup : public LLFloater, + public LLFloaterSingleton { + friend class LLUISingleton >; + +protected: + LOG_CLASS(LLObjectBackup); + public: - virtual ~LLObjectBackup(); + /////////////////////////////////////////////////////////////////////////// + // LLFloater interface - // Floater stuff - virtual void show(bool exporting); - virtual void onClose(bool app_quitting); + /*virtual*/ ~LLObjectBackup(); + /*virtual*/ void onClose(bool app_quitting); - // Static accessor - static LLObjectBackup* getInstance(); - static bool instanceExists() { return sInstance != NULL; } - - // Export idle callback - static void exportWorker(void *userdata); + /////////////////////////////////////////////////////////////////////////// + // Public interface for invoking the object backup feature // Import entry point void importObject(bool upload = false); @@ -70,47 +85,44 @@ public: void exportObject(); void exportObject_continued(AIFilePicker* filepicker); + /////////////////////////////////////////////////////////////////////////// + // Public methods used in callbacks, workers and responders + // Update map from texture worker void updateMap(LLUUID uploaded_asset); - // Move to next texture upload + // Move to next texture upload, called by the agent inventory responder void uploadNextAsset(); - // Folder public geter - std::string getfolder() { return mFolder; } + // Export idle callback + static void exportWorker(void *userdata); - // Prim updated callback - void primUpdate(LLViewerObject* object); + // Prim updated callback, called in llviewerobjectlist.cpp + static void primUpdate(LLViewerObject* object); - // New prim call back - bool newPrim(LLViewerObject* pobject); + // New prim call back, called in llviewerobjectlist.cpp + static void newPrim(LLViewerObject* object); - 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; + // Folder public getter, used by the texture cache responder + std::string getFolder() { return mFolder; } - // Set when the region supports the extra physics flags - bool mGotExtraPhysics; - - // Are we ready to check for next texture? - bool mCheckNextTexture; - - // Export state machine - enum export_states mExportState; - - // Export result flags for textures. - U32 mNonExportedTextures; static void setDefaultTextures(); - // Is exporting these objects allowed - bool validatePerms(const LLPermissions* item_permissions); + // Permissions checking + static bool validatePerms(const LLPermissions* item_permissions); + static bool validateTexturePerms(const LLUUID& asset_id); + static bool validateNode(LLSelectNode* node); private: - LLObjectBackup(); + // Open only via the importObject() and exportObject() methods defined + // above. + LLObjectBackup(const LLSD&); + + void showFloater(bool exporting); + + static bool confirmCloseCallback(const LLSD& notification, + const LLSD& response); // Update the floater with status numbers void updateImportNumbers(); @@ -133,7 +145,7 @@ private: void exportNextTexture(); // Apply LLSD to object - void xmlToPrim(LLSD prim_llsd, LLViewerObject* pobject); + void xmlToPrim(LLSD prim_llsd, LLViewerObject* object); // Rez a prim at a given position void rezAgentOffset(LLVector3 offset); @@ -141,9 +153,28 @@ private: // Get an offset from the agent based on rotation and current pos LLVector3 offsetAgent(LLVector3 offset); -private: - static LLObjectBackup* sInstance; +public: + // Public static constants, used in callbacks, workers and responders + 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; + // Export state machine + enum export_states mExportState; + + // Export result flags for textures. + U32 mNonExportedTextures; + + // Set when the region supports the extra physics flags + bool mGotExtraPhysics; + + // Are we ready to check for next texture? + bool mCheckNextTexture; + +private: // Are we active flag bool mRunning; @@ -156,7 +187,7 @@ private: U32 mPrims; U32 mCurPrim; - // No prims rezed + // Number of rezzed prims U32 mRezCount; // Root pos and rotation and central root pos for link set @@ -168,31 +199,39 @@ private: // Agent inital pos and rot when starting import LLVector3 mAgentPos; LLQuaternion mAgentRot; - // Rebase map - boost::unordered_map mAssetMap; + + LLUUID mCurrentAsset; + LLUUID mExpectingUpdate; + + // Working llsd iterators for objects and linksets + LLSD::map_const_iterator mPrimImportIter; + LLSD::array_const_iterator mGroupPrimImportIter; + + // File and folder name control + std::string mFileName; + std::string mFolder; // Export texture list typedef boost::unordered_set textures_set_t; textures_set_t mTexturesList; textures_set_t mBadPermsTexturesList; + // Rebase map + boost::unordered_map mAssetMap; + // Import object tracking std::vector mToSelect; std::vector::iterator mProcessIter; - // File and folder name control - std::string mFileName; - std::string mFolder; - // Working LLSD holders - LLUUID mCurrentAsset; - LLUUID mExpectingUpdate; LLSD mLLSD; LLSD mThisGroup; - - // Working llsd itterators for objects and linksets - LLSD::map_const_iterator mPrimImportIter; - LLSD::array_const_iterator mGroupPrimImportIter; }; -#endif \ No newline at end of file +extern LLUUID LL_TEXTURE_PLYWOOD; +extern LLUUID LL_TEXTURE_BLANK; +extern LLUUID LL_TEXTURE_INVISIBLE; +extern LLUUID LL_TEXTURE_TRANSPARENT; +extern LLUUID LL_TEXTURE_MEDIA; + +#endif // LL_LLVIEWEROBJECTBACKUP_H diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 2f9317090..6220096b9 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -272,7 +272,7 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, } else { - LLObjectBackup::getInstance()->primUpdate(objectp); + LLObjectBackup::primUpdate(objectp); } @@ -310,7 +310,7 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, gViewerWindow->getWindow()->decBusyCount(); gViewerWindow->getWindow()->setCursor( UI_CURSOR_ARROW ); - LLObjectBackup::getInstance()->newPrim(objectp); + LLObjectBackup::newPrim(objectp); } } diff --git a/indra/newview/skins/default/xui/en-us/floater_object_backup.xml b/indra/newview/skins/default/xui/en-us/floater_object_backup.xml index 060c4421e..dc9390ed8 100644 --- a/indra/newview/skins/default/xui/en-us/floater_object_backup.xml +++ b/indra/newview/skins/default/xui/en-us/floater_object_backup.xml @@ -1,6 +1,14 @@ - - Progress + + + Progress + + + Object export + + + Object import + diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index f1315772a..5284cbd0f 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -5938,11 +5938,25 @@ A login URI is required to retrieve the grid info. Builds with extended hollow or extended hole size do not render properly on other viewers. Please keep this option checked, if you want your builds looking properly in other viewers. + +Bad XML file. Import aborted. + + + +The Object was deselected before the export could occur. Export aborted. + + -None of the selected objects are exportable. Export aborted. +Bad permissions for the exported object. Export aborted. + +Are you sure you want to abort the current object backup operation? +
+