diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 48 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.h | 9 | ||||
| -rw-r--r-- | indra/newview/llinventorybridge.cpp | 42 | ||||
| -rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 76 | ||||
| -rw-r--r-- | indra/newview/llinventoryfunctions.h | 1 | ||||
| -rw-r--r-- | indra/newview/llinventorygallery.cpp | 41 | ||||
| -rw-r--r-- | indra/newview/llinventorygallerymenu.cpp | 43 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 6 | 
8 files changed, 176 insertions, 90 deletions
| diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 8673dc6a33..10b3f4b573 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1399,7 +1399,7 @@ const std::string LLAppearanceMgr::sExpectedTextureName = "OutfitPreview";  const LLUUID LLAppearanceMgr::getCOF() const  { -	return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); +	return mCOFID;  }  S32 LLAppearanceMgr::getCOFVersion() const @@ -1415,6 +1415,11 @@ S32 LLAppearanceMgr::getCOFVersion() const  	}  } +void LLAppearanceMgr::initCOFID() +{ +    mCOFID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); +} +  const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()  {  	const LLUUID& current_outfit_cat = getCOF(); @@ -3749,6 +3754,14 @@ LLSD LLAppearanceMgr::dumpCOF() const  	return result;  } +void LLAppearanceMgr::cleanup() +{ +    mIsInUpdateAppearanceFromCOF = false; +    mOutstandingAppearanceBakeRequest = false; +    mRerequestAppearanceBake = false; +    mCOFID.setNull(); +} +  // static  void LLAppearanceMgr::onIdle(void *)  { @@ -4387,20 +4400,45 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const  	return FALSE;  } -BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const +bool LLAppearanceMgr::getIsInCOF(const LLInventoryObject* obj) const  { -	if (!getIsInCOF(obj_id)) return FALSE; +    const LLUUID& cof = getCOF(); +    if (obj->getUUID() == cof) +        return true; +    if (obj && obj->getParentUUID() == cof) +        return true; +    return false; +} + +bool LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const +{ +	if (!getIsInCOF(obj_id)) return false;  	// If a non-link somehow ended up in COF, allow deletion.  	const LLInventoryObject *obj = gInventory.getObject(obj_id);  	if (obj && !obj->getIsLinkType())  	{ -		return FALSE; +		return false;  	}  	// For now, don't allow direct deletion from the COF.  Instead, force users  	// to choose "Detach" or "Take Off". -	return TRUE; +	return true; +} + +bool LLAppearanceMgr::getIsProtectedCOFItem(const LLInventoryObject* obj) const +{ +    if (!getIsInCOF(obj)) return false; + +    // If a non-link somehow ended up in COF, allow deletion. +    if (obj && !obj->getIsLinkType()) +    { +        return false; +    } + +    // For now, don't allow direct deletion from the COF.  Instead, force users +    // to choose "Detach" or "Take Off". +    return true;  }  class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 80d6587ad3..02859dc12c 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -111,9 +111,11 @@ public:  	// Find the Current Outfit folder.  	const LLUUID getCOF() const;  	S32 getCOFVersion() const; +    void initCOFID();  	// Debugging - get truncated LLSD summary of COF contents.  	LLSD dumpCOF() const; +    void cleanup();  	// Finds the folder link to the currently worn outfit  	const LLViewerInventoryItem *getBaseOutfitLink(); @@ -276,6 +278,7 @@ private:  	attachments_changed_signal_t		mAttachmentsChangeSignal;  	LLUUID mCOFImageID; +    LLUUID mCOFID;  	std::unique_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; @@ -290,8 +293,10 @@ private:  public:  	// Is this in the COF?  	BOOL getIsInCOF(const LLUUID& obj_id) const; -	// Is this in the COF and can the user delete it from the COF? -	BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; +    bool getIsInCOF(const LLInventoryObject* obj) const; +    // Is this in the COF and can the user delete it from the COF? +    bool getIsProtectedCOFItem(const LLUUID& obj_id) const; +    bool getIsProtectedCOFItem(const LLInventoryObject* obj) const;  	// Outfits will prioritize textures with such name to use for preview in gallery  	static const std::string sExpectedTextureName; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a12c4f7f76..4fb60b4c55 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2399,49 +2399,19 @@ void LLFolderBridge::update()  	}  } - -// Iterate through a folder's children to determine if -// all the children are removable. -class LLIsItemRemovable : public LLFolderViewFunctor -{ -public: -	LLIsItemRemovable(bool check_worn = true) : mPassed(TRUE), mCheckWorn(check_worn) {} -	virtual void doFolder(LLFolderViewFolder* folder) -	{ -		mPassed &= folder->getViewModelItem()->isItemRemovable(mCheckWorn); -	} -	virtual void doItem(LLFolderViewItem* item) -	{ -		mPassed &= item->getViewModelItem()->isItemRemovable(mCheckWorn); -	} -	BOOL mPassed; -    bool mCheckWorn; -}; -  // Can be destroyed (or moved to trash)  BOOL LLFolderBridge::isItemRemovable(bool check_worn) const  { -	if (!get_is_category_removable(getInventoryModel(), mUUID)) +	if (!get_is_category_and_children_removable(getInventoryModel(), mUUID, check_worn))  	{  		return FALSE;  	} -	LLInventoryPanel* panel = mInventoryPanel.get(); -	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ?   panel->getItemByID(mUUID) : NULL); -	if (folderp) -	{ -		LLIsItemRemovable folder_test(check_worn); -		folderp->applyFunctorToChildren(folder_test); -		if (!folder_test.mPassed) -		{ -			return FALSE; -		} -	} - -	if (isMarketplaceListingsFolder() && (!LLMarketplaceData::instance().isSLMDataFetched() || LLMarketplaceData::instance().getActivationState(mUUID))) -	{ -		return FALSE; -	} +    if (isMarketplaceListingsFolder() +        && (!LLMarketplaceData::instance().isSLMDataFetched() || LLMarketplaceData::instance().getActivationState(mUUID))) +    { +        return FALSE; +    }  	return TRUE;  } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index c2cbf4b8ac..5d6bf8ab4b 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -621,7 +621,7 @@ BOOL get_is_item_worn(const LLUUID& id, const LLViewerInventoryItem* item)  BOOL get_is_item_worn(const LLUUID& id)  {      const LLViewerInventoryItem* item = gInventory.getItem(id); -    return get_is_item_worn(item); +    return get_is_item_worn(id, item);  }  BOOL get_is_item_worn(const LLViewerInventoryItem* item) @@ -711,20 +711,20 @@ bool get_is_item_removable(const LLInventoryModel* model, const LLUUID& id, bool  	// Disable delete from COF folder; have users explicitly choose "detach/take off",  	// unless the item is not worn but in the COF (i.e. is bugged). -	if (LLAppearanceMgr::instance().getIsProtectedCOFItem(id)) +    const LLViewerInventoryItem* obj = model->getItem(id); +	if (LLAppearanceMgr::instance().getIsProtectedCOFItem(obj))  	{ -		if (get_is_item_worn(id)) +		if (get_is_item_worn(id, obj))  		{  			return false;  		}  	} -	const LLInventoryObject *obj = model->getItem(id);  	if (obj && obj->getIsLinkType())  	{  		return true;  	} -	if (check_worn && get_is_item_worn(id)) +	if (check_worn && get_is_item_worn(id, obj))  	{  		return false;  	} @@ -819,6 +819,72 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)  	return TRUE;  } +bool get_is_category_and_children_removable(LLInventoryModel* model, const LLUUID& folder_id, bool check_worn) +{ +    if (!get_is_category_removable(model, folder_id)) +    { +        return false; +    } + +    const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); +    if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id)) +    { +        return false; +    } + +    LLInventoryModel::cat_array_t cat_array; +    LLInventoryModel::item_array_t item_array; +    model->collectDescendents( +        folder_id, +        cat_array, +        item_array, +        LLInventoryModel::EXCLUDE_TRASH); + +    for (LLInventoryModel::item_array_t::value_type& item : item_array) +    { +        // Disable delete from COF folder; have users explicitly choose "detach/take off", +        // unless the item is not worn but in the COF (i.e. is bugged). +        if (LLAppearanceMgr::instance().getIsProtectedCOFItem(item)) +        { +            if (get_is_item_worn(item)) +            { +                return false; +            } +        } + +        if (item && item->getIsLinkType()) +        { +            return true; +        } +        if (check_worn && get_is_item_worn(item)) +        { +            return false; +        } +    } + +    const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); +    LLViewerInventoryCategory* outfit_linked_category = base_outfit_link ? base_outfit_link->getLinkedCategory() : nullptr; +    for (LLInventoryModel::cat_array_t::value_type& cat : cat_array) +    { +        const LLFolderType::EType folder_type = cat->getPreferredType(); +        if (LLFolderType::lookupIsProtectedType(folder_type)) +        { +            return false; +        } + +        // Can't delete the outfit that is currently being worn. +        if (folder_type == LLFolderType::FT_OUTFIT) +        { +            if (cat == outfit_linked_category) +            { +                return false; +            } +        } +    } + +    return true; +} +  BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)  {  	if (!model) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index a8a9bb9735..deacaced42 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -59,6 +59,7 @@ bool get_is_item_editable(const LLUUID& inv_item_id);  void handle_item_edit(const LLUUID& inv_item_id);  BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id); +bool get_is_category_and_children_removable(LLInventoryModel* model, const LLUUID& folder_id, bool check_worn);  BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id); diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index ad6c3909ef..3c3da253d3 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -1668,6 +1668,45 @@ void LLInventoryGallery::cut()      mFilterSubString.clear();  } + + +bool is_category_removable(const LLUUID& folder_id, bool check_worn) +{ +    if (!get_is_category_removable(&gInventory, folder_id)) +    { +        return false; +    } + +    // check children +    LLInventoryModel::cat_array_t* cat_array; +    LLInventoryModel::item_array_t* item_array; +    gInventory.getDirectDescendentsOf(folder_id, cat_array, item_array); + +    for (LLInventoryModel::item_array_t::value_type& item : *item_array) +    { +        if (!get_is_item_removable(&gInventory, item->getUUID(), check_worn)) +        { +            return false; +        } +    } + +    for (LLInventoryModel::cat_array_t::value_type& cat : *cat_array) +    { +        if (!is_category_removable(cat->getUUID(), check_worn)) +        { +            return false; +        } +    } + +    const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); +    if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id)) +    { +        return false; +    } + +    return true; +} +  BOOL LLInventoryGallery::canCut() const  {      if (!getVisible() || !getEnabled() || mSelectedItemIDs.empty()) @@ -1680,7 +1719,7 @@ BOOL LLInventoryGallery::canCut() const          LLViewerInventoryCategory* cat = gInventory.getCategory(id);          if (cat)          { -            if (!get_is_category_removable(&gInventory, id)) +            if (!get_is_category_and_children_removable(&gInventory, id, true))              {                  return FALSE;              } diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 2bca33dec4..4b47346473 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -388,43 +388,6 @@ bool is_inbox_folder(LLUUID item_id)      return gInventory.isObjectDescendentOf(item_id, inbox_id);  } -bool is_category_removable(const LLUUID &folder_id, bool check_worn) -{ -    if (!get_is_category_removable(&gInventory, folder_id)) -    { -        return false; -    } - -    // check children -    LLInventoryModel::cat_array_t* cat_array; -    LLInventoryModel::item_array_t* item_array; -    gInventory.getDirectDescendentsOf(folder_id, cat_array, item_array); - -    for (LLInventoryModel::item_array_t::value_type& item : *item_array) -    { -        if (!get_is_item_removable(&gInventory, item->getUUID(), check_worn)) -        { -            return false; -        } -    } - -    for (LLInventoryModel::cat_array_t::value_type& cat : *cat_array) -    { -        if (!is_category_removable(cat->getUUID(), check_worn)) -        { -            return false; -        } -    } - -    const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); -    if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id)) -    { -        return false; -    } - -    return true; -} -  void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* menu)  {      LLUUID selected_id = mUUIDs.front(); @@ -532,7 +495,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men              }          }          items.push_back(std::string("Purge Item")); -        if (is_folder && !is_category_removable(selected_id, true)) +        if (is_folder && !get_is_category_and_children_removable(&gInventory, selected_id, true))          {              disabled_items.push_back(std::string("Purge Item"));          } @@ -580,12 +543,12 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men                  items.push_back(std::string("Cut"));                  items.push_back(std::string("Delete")); -                if(!is_category_removable(selected_id, false)) +                if(!get_is_category_and_children_removable(&gInventory, selected_id, false))                  {                      disabled_items.push_back(std::string("Delete"));                      disabled_items.push_back(std::string("Cut"));                  } -                else if (!is_category_removable(selected_id, true)) +                else if (!get_is_category_and_children_removable(&gInventory, selected_id, true))                  {                      disabled_items.push_back(std::string("Cut"));                  } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 916848ff5f..bb867f7b23 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1938,8 +1938,10 @@ bool idle_startup()              display_startup();              return FALSE;          } +          LLInventoryModelBackgroundFetch::instance().start(); -        LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); +        LLAppearanceMgr::instance().initCOFID(); +        LLUUID cof_id = LLAppearanceMgr::instance().getCOF();          LLViewerInventoryCategory* cof = gInventory.getCategory(cof_id);          if (cof              && cof->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) @@ -2812,6 +2814,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,  	LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);  	// Initiate creation of COF, since we're also bypassing that.  	gInventory.ensureCategoryForTypeExists(LLFolderType::FT_CURRENT_OUTFIT); +    LLAppearanceMgr::getInstance()->initCOFID();  	ESex gender;  	if (gender_name == "male") @@ -2968,6 +2971,7 @@ void reset_login()  	gAgent.cleanup();      gSky.cleanup(); // mVOSkyp is an inworld object.  	LLWorld::getInstance()->resetClass(); +    LLAppearanceMgr::getInstance()->cleanup();  	if ( gViewerWindow )  	{	// Hide menus and normal buttons | 
