diff options
Diffstat (limited to 'indra/newview/llinventorybridge.cpp')
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 301 |
1 files changed, 169 insertions, 132 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 26a8a707b8..3fc2cbecbe 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -190,12 +190,7 @@ BOOL LLInvFVBridge::isItemRemovable() { return TRUE; } - if (gAgentWearables.isWearingItem(mUUID)) - { - return FALSE; - } - const LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - if (avatar && avatar->isWearingAttachment(mUUID)) + if (get_is_item_worn(mUUID)) { return FALSE; } @@ -506,41 +501,6 @@ void hide_context_entries(LLMenuGL& menu, } } -bool isWornLink(LLUUID link_id) -{ - LLViewerInventoryItem *link = gInventory.getItem(link_id); - if (!link) - return false; - LLViewerInventoryItem *item = link->getLinkedItem(); - if (!item) - return false; - - switch(item->getType()) - { - case LLAssetType::AT_OBJECT: - { - LLVOAvatarSelf* my_avatar = gAgent.getAvatarObject(); - if(my_avatar && my_avatar->isWearingAttachment(item->getUUID())) - return true; - } - break; - - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_CLOTHING: - if(gAgentWearables.isWearingItem(item->getUUID())) - return true; - break; - - case LLAssetType::AT_GESTURE: - if (LLGestureManager::instance().isGestureActive(item->getUUID())) - return true; - break; - default: - break; - } - return false; -} - // Helper for commonly-used entries void LLInvFVBridge::getClipboardEntries(bool show_asset_id, std::vector<std::string> &items, @@ -552,7 +512,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (is_sidepanel) { // Sidepanel includes restricted menu. - if (obj && obj->getIsLinkType() && !isWornLink(mUUID)) + if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID)) { items.push_back(std::string("Remove Link")); } @@ -606,15 +566,18 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Paste")); } - items.push_back(std::string("Paste As Link")); - if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) + if (gAgent.isGodlike()) { - disabled_items.push_back(std::string("Paste As Link")); + items.push_back(std::string("Paste As Link")); + if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Paste As Link")); + } } items.push_back(std::string("Paste Separator")); - if (obj && obj->getIsLinkType() && !isWornLink(mUUID)) + if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID)) { items.push_back(std::string("Remove Link")); } @@ -973,7 +936,7 @@ bool LLInvFVBridge::isInOutfitsSidePanel() const dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory")); if (!outfit_panel) return false; - return outfit_panel->isAccordionPanel(my_panel); + return outfit_panel->isTabPanel(my_panel); } // +=================================================+ @@ -1196,7 +1159,7 @@ LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const { U8 font = LLFontGL::NORMAL; - if( gAgentWearables.isWearingItem( mUUID ) ) + if (get_is_item_worn(mUUID)) { // llinfos << "BOLD" << llendl; font |= LLFontGL::BOLD; @@ -1339,29 +1302,33 @@ BOOL LLItemBridge::isItemCopyable() const LLViewerInventoryItem* item = getItem(); if (item) { - // can't copy worn objects. DEV-15183 - LLVOAvatarSelf *avatarp = gAgent.getAvatarObject(); - if( !avatarp ) + // Can't copy worn objects. DEV-15183 + if(get_is_item_worn(mUUID)) { return FALSE; } - if(avatarp->isWearingAttachment(mUUID)) + // You can never copy a link. + if (item->getIsLinkType()) { return FALSE; } - // All items can be copied, not all can be pasted. - // The only time an item can't be copied is if it's a link - // return (item->getPermissions().allowCopyBy(gAgent.getID())); - if (item->getIsLinkType()) + if (gAgent.isGodlike()) { - return FALSE; + // All items can be copied in god mode since you can + // at least paste-as-link the item, though you + // still may not be able paste the item. + return TRUE; + } + else + { + return (item->getPermissions().allowCopyBy(gAgent.getID())); } - return TRUE; } return FALSE; } + BOOL LLItemBridge::copyToClipboard() const { if(isItemCopyable()) @@ -1471,13 +1438,11 @@ BOOL LLFolderBridge::isItemRemovable() { return FALSE; } - // Allow protected types to be removed, but issue a warning. - /* + if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) { return FALSE; } - */ LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL); @@ -1680,23 +1645,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, for( i = 0; i < descendent_items.count(); i++ ) { LLInventoryItem* item = descendent_items[i]; - if( (item->getType() == LLAssetType::AT_CLOTHING) || - (item->getType() == LLAssetType::AT_BODYPART) ) - { - if( gAgentWearables.isWearingItem( item->getUUID() ) ) - { - is_movable = FALSE; // It's generally movable, but not into the trash! - break; - } - } - else - if( item->getType() == LLAssetType::AT_OBJECT ) + if (get_is_item_worn(item->getUUID())) { - if( avatar->isWearingAttachment( item->getUUID() ) ) - { - is_movable = FALSE; // It's generally movable, but not into the trash! - break; - } + is_movable = FALSE; + break; // It's generally movable, but not into the trash! } } } @@ -2186,6 +2138,12 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model restoreItem(); return; } +#ifndef LL_RELEASE_FOR_DOWNLOAD + else if ("delete_system_folder" == action) + { + removeSystemFolder(); + } +#endif } void LLFolderBridge::openItem() @@ -2309,13 +2267,27 @@ BOOL LLFolderBridge::removeItem() LLNotification::Params params("ConfirmDeleteProtectedCategory"); params.payload(payload).substitutions(args).functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2)); - if (LLFolderType::lookupIsProtectedType(cat->getPreferredType())) + LLNotifications::instance().forceResponse(params, 0); + return TRUE; +} + + +BOOL LLFolderBridge::removeSystemFolder() +{ + const LLViewerInventoryCategory *cat = getCategory(); + if (!LLFolderType::lookupIsProtectedType(cat->getPreferredType())) { - LLNotifications::instance().add(params); + return FALSE; } - else + + LLSD payload; + LLSD args; + args["FOLDERNAME"] = cat->getName(); + + LLNotification::Params params("ConfirmDeleteProtectedCategory"); + params.payload(payload).substitutions(args).functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2)); { - LLNotifications::instance().forceResponse(params, 0); + LLNotifications::instance().add(params); } return TRUE; } @@ -2484,6 +2456,13 @@ void LLFolderBridge::folderOptionsMenu() } } +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (LLFolderType::lookupIsProtectedType(type)) + { + mItems.push_back(std::string("Delete System Folder")); + } +#endif + // wearables related functionality for folders. //is_wearable LLFindWearables is_wearable; @@ -2495,7 +2474,10 @@ void LLFolderBridge::folderOptionsMenu() checkFolderForContentsOfType(model, is_object) || checkFolderForContentsOfType(model, is_gesture) ) { - mItems.push_back(std::string("Folder Wearables Separator")); + if (!is_sidepanel) + { + mItems.push_back(std::string("Folder Wearables Separator")); + } // Only enable add/replace outfit for non-default folders. if (!is_default_folder) @@ -2508,8 +2490,11 @@ void LLFolderBridge::folderOptionsMenu() mItems.push_back(std::string("Wear As Ensemble")); } mItems.push_back(std::string("Remove From Outfit")); - if (is_sidepanel) - mItems.push_back(std::string("Outfit Separator")); + if (!areAnyContentsWorn(model)) + { + disabled_items.push_back(std::string("Remove From Outfit")); + } + mItems.push_back(std::string("Outfit Separator")); } hide_context_entries(*mMenu, mItems, disabled_items); @@ -2530,6 +2515,35 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv return ((item_array.count() > 0) ? TRUE : FALSE ); } +class LLFindWorn : public LLInventoryCollectFunctor +{ +public: + LLFindWorn() {} + virtual ~LLFindWorn() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item) + { + if (item && get_is_item_worn(item->getUUID())) + { + return TRUE; + } + return FALSE; + } +}; + +BOOL LLFolderBridge::areAnyContentsWorn(LLInventoryModel* model) const +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + LLFindWorn is_worn; + model->collectDescendentsIf(mUUID, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_worn); + return (item_array.size() > 0); +} + // Flags unused void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { @@ -2652,6 +2666,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mItems.push_back(std::string("--no options--")); mDisabledItems.push_back(std::string("--no options--")); } + + // Preemptively disable system folder removal if more than one item selected. + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + mDisabledItems.push_back(std::string("Delete System Folder")); + } + hide_context_entries(menu, mItems, mDisabledItems); } @@ -2901,6 +2922,9 @@ void saveItemsOrder(LLInventoryModel::item_array_t& items) item->updateServer(FALSE); gInventory.updateItem(item); + + // Tell the parent folder to refresh its sort order. + gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID()); } gInventory.notifyObservers(); @@ -2922,6 +2946,27 @@ LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_a return result; } +// See also LLInventorySort where landmarks in the Favorites folder are sorted. +class LLViewerInventoryItemSort +{ +public: + bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b) + { + return a->getSortField() < b->getSortField(); + } +}; + +/** + * Sorts passed items by LLViewerInventoryItem sort field. + * + * @param[in, out] items - array of items, not sorted. + */ +void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items) +{ + static LLViewerInventoryItemSort sort_functor; + std::sort(items.begin(), items.end(), sort_functor); +} + void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId) { LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId); @@ -2970,19 +3015,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if(is_movable && move_is_into_trash) { - switch(inv_item->getType()) - { - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_BODYPART: - is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID()); - break; - - case LLAssetType::AT_OBJECT: - is_movable = !avatar->isWearingAttachment(inv_item->getUUID()); - break; - default: - break; - } + is_movable = inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID()); } if ( is_movable ) @@ -2997,8 +3030,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } const LLUUID& favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - const LLUUID& landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK); - const BOOL folder_allows_reorder = ((mUUID == landmarks_id) || (mUUID == favorites_id)); + const BOOL folder_allows_reorder = (mUUID == favorites_id); // we can move item inside a folder only if this folder is Favorites. See EXT-719 accept = is_movable && ((mUUID != inv_item->getParentUUID()) || folder_allows_reorder); @@ -3013,7 +3045,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // everything in the active window so that we don't follow // the selection to its new location (which is very // annoying). - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); if (active_panel) { LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); @@ -3038,6 +3070,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, LLUUID srcItemId = inv_item->getUUID(); LLUUID destItemId = itemp->getListener()->getUUID(); + // ensure items are sorted properly before changing order. EXT-3498 + rearrange_item_order_by_sort_field(items); + // update order updateItemsOrder(items, srcItemId, destItemId); @@ -4050,8 +4085,7 @@ LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const { U8 font = LLFontGL::NORMAL; - LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - if( avatar && avatar->isWearingAttachment( mUUID ) ) + if(get_is_item_worn( mUUID ) ) { font |= LLFontGL::BOLD; } @@ -4067,9 +4101,9 @@ LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const std::string LLObjectBridge::getLabelSuffix() const { - LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - if( avatar && avatar->isWearingAttachment( mUUID ) ) + if (get_is_item_worn(mUUID)) { + LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); std::string attachment_point_name = avatar->getAttachedPointName(mUUID); // e.g. "(worn on ...)" / "(attached to ...)" @@ -4194,12 +4228,11 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) return; } - if( avatarp->isWearingAttachment( mUUID ) ) + if( get_is_item_worn( mUUID ) ) { items.push_back(std::string("Detach From Yourself")); } - else - if( !isInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing()) + else if (!isInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing()) { items.push_back(std::string("Attach Separator")); items.push_back(std::string("Object Wear")); @@ -4425,7 +4458,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ if (gAgent.isTeen() && item->isWearableType() && (item->getWearableType() == WT_UNDERPANTS || item->getWearableType() == WT_UNDERSHIRT)) continue; - if( gAgentWearables.isWearingItem (item->getLinkedUUID()) ) + if (get_is_item_worn(item->getUUID())) { LLWearableList::instance().getAsset(item->getAssetUUID(), item->getName(), @@ -4441,18 +4474,21 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ for(i = 0; i < obj_count; ++i) { LLViewerInventoryItem *obj_item = obj_item_array.get(i); - gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData ); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item->getLinkedUUID() ); - - gMessageSystem->sendReliable( gAgent.getRegion()->getHost() ); - - // this object might have been selected, so let the selection manager know it's gone now - LLViewerObject *found_obj = gObjectList.findObject( obj_item->getLinkedUUID()); - if (found_obj) + if (get_is_item_worn(obj_item->getUUID())) { - LLSelectMgr::getInstance()->remove(found_obj); + gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData ); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item->getLinkedUUID() ); + + gMessageSystem->sendReliable( gAgent.getRegion()->getHost() ); + + // this object might have been selected, so let the selection manager know it's gone now + LLViewerObject *found_obj = gObjectList.findObject( obj_item->getLinkedUUID()); + if (found_obj) + { + LLSelectMgr::getInstance()->remove(found_obj); + } } } } @@ -4462,7 +4498,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ for(i = 0; i < gest_count; ++i) { LLViewerInventoryItem *gest_item = gest_item_array.get(i); - if ( LLGestureManager::instance().isGestureActive( gest_item->getLinkedUUID()) ) + if (get_is_item_worn(gest_item->getUUID())) { LLGestureManager::instance().deactivateGesture( gest_item->getLinkedUUID() ); gInventory.updateItem( gest_item ); @@ -4476,7 +4512,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ BOOL LLWearableBridge::renameItem(const std::string& new_name) { - if( gAgentWearables.isWearingItem( mUUID ) ) + if (get_is_item_worn(mUUID)) { gAgentWearables.setWearableName( mUUID, new_name ); } @@ -4485,7 +4521,7 @@ BOOL LLWearableBridge::renameItem(const std::string& new_name) std::string LLWearableBridge::getLabelSuffix() const { - if( gAgentWearables.isWearingItem( mUUID ) ) + if (get_is_item_worn(mUUID)) { // e.g. "(worn)" return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn"); @@ -4519,7 +4555,7 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod } else if (isRemoveAction(action)) { - if(gAgentWearables.isWearingItem(mUUID)) + if (get_is_item_worn(mUUID)) { LLViewerInventoryItem* item = getItem(); if (item) @@ -4550,7 +4586,7 @@ void LLWearableBridge::openItem() } else if(isAgentInventory()) { - if( !gAgentWearables.isWearingItem( mUUID ) ) + if( !get_is_item_worn( mUUID ) ) { wearOnAvatar(); } @@ -4650,7 +4686,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) case LLAssetType::AT_CLOTHING: items.push_back(std::string("Take Off")); case LLAssetType::AT_BODYPART: - if (gAgentWearables.isWearingItem(item->getUUID())) + if (get_is_item_worn(item->getUUID())) { disabled_items.push_back(std::string("Wearable Wear")); disabled_items.push_back(std::string("Wearable Add")); @@ -4681,7 +4717,7 @@ BOOL LLWearableBridge::canWearOnAvatar(void* user_data) LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem(); if(!item || !item->isComplete()) return FALSE; } - return (!gAgentWearables.isWearingItem(self->mUUID)); + return (!get_is_item_worn(self->mUUID)); } // Called from menus @@ -4813,7 +4849,7 @@ BOOL LLWearableBridge::canEditOnAvatar(void* user_data) LLWearableBridge* self = (LLWearableBridge*)user_data; if(!self) return FALSE; - return (gAgentWearables.isWearingItem(self->mUUID)); + return (get_is_item_worn(self->mUUID)); } // static @@ -4850,7 +4886,7 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data) LLWearableBridge* self = (LLWearableBridge*)user_data; if( self && (LLAssetType::AT_BODYPART != self->mAssetType) ) { - return gAgentWearables.isWearingItem( self->mUUID ); + return get_is_item_worn( self->mUUID ); } return FALSE; } @@ -4860,7 +4896,7 @@ void LLWearableBridge::onRemoveFromAvatar(void* user_data) { LLWearableBridge* self = (LLWearableBridge*)user_data; if(!self) return; - if(gAgentWearables.isWearingItem(self->mUUID)) + if(get_is_item_worn(self->mUUID)) { LLViewerInventoryItem* item = self->getItem(); if (item) @@ -4883,7 +4919,7 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID); if(wearable) { - if( gAgentWearables.isWearingItem( item_id ) ) + if( get_is_item_worn( item_id ) ) { EWearableType type = wearable->getType(); @@ -5093,8 +5129,9 @@ void LLAnimationBridgeAction::doIt() //virtual void LLObjectBridgeAction::doIt() { + /* LLFloaterReg::showInstance("properties", mUUID); - + */ LLInvFVBridgeAction::doIt(); } @@ -5166,7 +5203,7 @@ void LLWearableBridgeAction::doIt() } else if(isAgentInventory()) { - if(!gAgentWearables.isWearingItem(mUUID)) + if(!get_is_item_worn(mUUID)) { wearOnAvatar(); } |