diff options
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rw-r--r-- | indra/newview/llagentwearables.cpp | 227 |
1 files changed, 142 insertions, 85 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index d823a3cbbb..a1ce556458 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -2,31 +2,25 @@ * @file llagentwearables.cpp * @brief LLAgentWearables class implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -47,7 +41,7 @@ #include "llinventorypanel.h" #include "llmd5.h" #include "llnotificationsutil.h" -#include "llpaneloutfitsinventory.h" +#include "lloutfitobserver.h" #include "llsidepanelappearance.h" #include "llsidetray.h" #include "lltexlayer.h" @@ -64,6 +58,25 @@ BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; using namespace LLVOAvatarDefines; +/////////////////////////////////////////////////////////////////////////////// + +// Callback to wear and start editing an item that has just been created. +class LLWearAndEditCallback : public LLInventoryCallback +{ + void fire(const LLUUID& inv_item) + { + if (inv_item.isNull()) return; + + // Request editing the item after it gets worn. + gAgentWearables.requestEditingWearable(inv_item); + + // Wear it. + LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); + } +}; + +/////////////////////////////////////////////////////////////////////////////// + // HACK: For EXT-3923: Pants item shows in inventory with skin icon and messes with "current look" // Some db items are corrupted, have inventory flags = 0, implying wearable type = shape, even though // wearable type stored in asset is some other value. @@ -147,6 +160,7 @@ struct LLAgentDumper LLAgentWearables::LLAgentWearables() : mWearablesLoaded(FALSE) +, mCOFChangeInProgress(false) { } @@ -159,6 +173,14 @@ void LLAgentWearables::cleanup() { } +// static +void LLAgentWearables::initClass() +{ + // this can not be called from constructor because its instance is global and is created too early. + // Subscribe to "COF is Saved" signal to notify observers about this (Loading indicator for ex.). + LLOutfitObserver::instance().addCOFSavedCallback(boost::bind(&LLAgentWearables::notifyLoadingFinished, &gAgentWearables)); +} + void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) { if (avatar) @@ -356,7 +378,8 @@ void LLAgentWearables::sendAgentWearablesUpdate() gAgent.sendReliableMessage(); } -void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update) +void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update, + const std::string new_name) { LLWearable* old_wearable = getWearable(type, index); if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion())) @@ -374,6 +397,14 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 LLInventoryItem* item = gInventory.getItem(old_item_id); if (item) { + std::string item_name = item->getName(); + bool name_changed = false; + if (!new_name.empty() && (new_name != item->getName())) + { + llinfos << "saveWearable changing name from " << item->getName() << " to " << new_name << llendl; + item_name = new_name; + name_changed = true; + } // Update existing inventory item LLPointer<LLViewerInventoryItem> template_item = new LLViewerInventoryItem(item->getUUID(), @@ -382,7 +413,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 new_wearable->getAssetID(), new_wearable->getAssetType(), item->getInventoryType(), - item->getName(), + item_name, item->getDescription(), item->getSaleInfo(), item->getFlags(), @@ -390,6 +421,10 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 template_item->setTransactionID(new_wearable->getTransactionID()); template_item->updateServer(FALSE); gInventory.updateItem(template_item); + if (name_changed) + { + gInventory.notifyObservers(); + } } else { @@ -483,7 +518,11 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type, void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index) { LLWearable* wearable = getWearable(type, index); - wearable->revertValues(); + llassert(wearable); + if (wearable) + { + wearable->revertValues(); + } gAgent.sendAgentSetAppearance(); } @@ -515,6 +554,7 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& { LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j); llassert(old_wearable); + if (!old_wearable) continue; std::string old_name = old_wearable->getName(); old_wearable->setName(new_name); @@ -732,7 +772,7 @@ U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable void LLAgentWearables::wearableUpdated(LLWearable *wearable) { - gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); + gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE); wearable->refreshName(); wearable->setLabelUpdated(); @@ -901,13 +941,19 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const // static // ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume // that viewers have a Current Outfit Folder and won't need this message, and thus -// we can remove/ignore this whole function. +// we can remove/ignore this whole function. EXCEPT gAgentWearables.notifyLoadingStarted void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data) { // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates // that may result from AgentWearablesRequest having been sent more than once. if (mInitialWearablesUpdateReceived) return; + + // notify subscribers that wearables started loading. See EXT-7777 + // *TODO: find more proper place to not be called from deprecated method. + // Seems such place is found: LLInitialWearablesFetch::processContents() + gAgentWearables.notifyLoadingStarted(); + mInitialWearablesUpdateReceived = true; LLUUID agent_id; @@ -1189,7 +1235,7 @@ void LLAgentWearables::createStandardWearablesAllDone() mWearablesLoaded = TRUE; checkWearablesLoaded(); - mLoadedSignal(); + notifyLoadingFinished(); updateServer(); @@ -1197,45 +1243,6 @@ void LLAgentWearables::createStandardWearablesAllDone() gAgentAvatarp->onFirstTEMessageReceived(); } - -class LLShowCreatedOutfit: public LLInventoryCallback -{ -public: - LLShowCreatedOutfit(LLUUID& folder_id): - mFolderID(folder_id) - { - } - - virtual ~LLShowCreatedOutfit() - { - LLSD key; - LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key); - LLPanelOutfitsInventory *outfit_panel = - dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory")); - // TODO: add handling "My Outfits" tab. - if (outfit_panel && outfit_panel->isCOFPanelActive()) - { - outfit_panel->getRootFolder()->clearSelection(); - outfit_panel->getRootFolder()->setSelectionByID(mFolderID, TRUE); - } - LLAccordionCtrlTab* tab_outfits = outfit_panel ? outfit_panel->findChild<LLAccordionCtrlTab>("tab_outfits") : 0; - if (tab_outfits && !tab_outfits->getDisplayChildren()) - { - tab_outfits->changeOpenClose(tab_outfits->getDisplayChildren()); - } - - LLAppearanceMgr::instance().updateIsDirty(); - LLAppearanceMgr::instance().updatePanelOutfitName(""); - } - - virtual void fire(const LLUUID&) - { - } - -private: - LLUUID mFolderID; -}; - void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index) { LLUUID first_item_id = getWearableItemID((LLWearableType::EType)type, index); @@ -1441,7 +1448,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // Start rendering & update the server mWearablesLoaded = TRUE; checkWearablesLoaded(); - mLoadedSignal(); + notifyLoadingFinished(); queryWearableCache(); updateServer(); @@ -1872,11 +1879,10 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra msg->nextBlockFast(_PREHASH_ObjectData ); msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); -#if ENABLE_MULTIATTACHMENTS - msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD ); -#else - msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point -#endif + if (gSavedSettings.getBOOL("MultipleAttachments")) + msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD ); + else + msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); msg->addStringFast(_PREHASH_Name, item->getName()); msg->addStringFast(_PREHASH_Description, item->getDescription()); @@ -1926,7 +1932,7 @@ void LLAgentWearables::updateWearablesLoaded() mWearablesLoaded = (itemUpdatePendingCount()==0); if (mWearablesLoaded) { - mLoadedSignal(); + notifyLoadingFinished(); } } @@ -1946,7 +1952,11 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake) for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count) { LLWearable *wearable = getWearable((LLWearableType::EType)type,count); - wearable->animateParams(delta, upload_bake); + llassert(wearable); + if (wearable) + { + wearable->animateParams(delta, upload_bake); + } } } } @@ -1987,10 +1997,12 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos // static void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id) { + if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; + LLWearable* wearable = LLWearableList::instance().createNewWearable(type); LLAssetType::EType asset_type = wearable->getAssetType(); LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; - LLPointer<LLInventoryCallback> cb = wear ? new WearOnAvatarCallback : NULL; + LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL; LLUUID folder_id; if (parent_id.notNull()) @@ -2013,17 +2025,44 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con // static void LLAgentWearables::editWearable(const LLUUID& item_id) { - LLViewerInventoryItem* item; - LLWearable* wearable; + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (!item) + { + llwarns << "Failed to get linked item" << llendl; + return; + } - if ((item = gInventory.getLinkedItem(item_id)) && - (wearable = gAgentWearables.getWearableFromAssetID(item->getAssetUUID())) && - gAgentWearables.isWearableModifiable(item->getUUID()) && - item->isFinished()) + LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); + if (!wearable) { - LLPanel* panel = LLSideTray::getInstance()->showPanel("panel_outfit_edit", LLSD()); - // copied from LLPanelOutfitEdit::onEditWearableClicked() - LLSidepanelAppearance::editWearable(wearable, panel->getParent()); + llwarns << "Cannot get wearable" << llendl; + return; + } + + if (!gAgentWearables.isWearableModifiable(item->getUUID())) + { + llwarns << "Cannot modify wearable" << llendl; + return; + } + + LLPanel* panel = LLSideTray::getInstance()->getPanel("sidepanel_appearance"); + LLSidepanelAppearance::editWearable(wearable, panel); +} + +// Request editing the item after it gets worn. +void LLAgentWearables::requestEditingWearable(const LLUUID& item_id) +{ + mItemToEdit = gInventory.getLinkedItemID(item_id); +} + +// Start editing the item if previously requested. +void LLAgentWearables::editWearableIfRequested(const LLUUID& item_id) +{ + if (mItemToEdit.notNull() && + mItemToEdit == gInventory.getLinkedItemID(item_id)) + { + LLAgentWearables::editWearable(item_id); + mItemToEdit.setNull(); } } @@ -2051,7 +2090,25 @@ void LLAgentWearables::populateMyOutfitsFolder(void) } } +boost::signals2::connection LLAgentWearables::addLoadingStartedCallback(loading_started_callback_t cb) +{ + return mLoadingStartedSignal.connect(cb); +} + boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_t cb) { return mLoadedSignal.connect(cb); } + +void LLAgentWearables::notifyLoadingStarted() +{ + mCOFChangeInProgress = true; + mLoadingStartedSignal(); +} + +void LLAgentWearables::notifyLoadingFinished() +{ + mCOFChangeInProgress = false; + mLoadedSignal(); +} +// EOF |