diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llmaterialeditor.cpp | 92 | ||||
| -rw-r--r-- | indra/newview/llpanelface.cpp | 65 | ||||
| -rw-r--r-- | indra/newview/llpanelface.h | 6 | 
3 files changed, 142 insertions, 21 deletions
| diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 5be1aa08ab..bae4afb7e6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -38,6 +38,7 @@  #include "llgltfmateriallist.h"  #include "llinventorymodel.h"  #include "llinventoryobserver.h" +#include "llinventoryfunctions.h"  #include "lllocalgltfmaterials.h"  #include "llnotificationsutil.h"  #include "lltexturectrl.h" @@ -1796,8 +1797,49 @@ void LLMaterialEditor::loadLive()      }  } +namespace +{ +    // Which inventory to consult for item permissions +    enum class ItemSource +    { +        // Consult the permissions of the item in the object's inventory. If +        // the item is not present, then usage of the asset is allowed. +        OBJECT, +        // Consult the permissions of the item in the agent's inventory. If +        // the item is not present, then usage of the asset is not allowed. +        AGENT +    }; + +    class LLAssetIDMatchesWithPerms : public LLInventoryCollectFunctor +    { +    public: +        LLAssetIDMatchesWithPerms(const LLUUID& asset_id, const std::vector<PermissionBit>& ops) : mAssetID(asset_id), mOps(ops) {} +        virtual ~LLAssetIDMatchesWithPerms() {} +        bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) +        { +            if (!item || item->getAssetUUID() != mAssetID) +            { +                return false; +            } +            LLPermissions item_permissions = item->getPermissions(); +            for (PermissionBit op : mOps) +            { +                if (!gAgent.allowOperation(op, item_permissions, GP_OBJECT_MANIPULATE)) +                { +                    return false; +                } +            } +            return true; +        } + +    protected: +        LLUUID mAssetID; +        std::vector<PermissionBit> mOps; +    }; +}; +  // *NOTE: permissions_out includes user preferences for new item creation (LLFloaterPerms) -bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<PermissionBit>& ops, LLPermissions& permissions_out, LLViewerInventoryItem*& item_out) +bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<PermissionBit>& ops, const ItemSource item_source, LLPermissions& permissions_out, LLViewerInventoryItem*& item_out)  {      if (!LLMaterialEditor::capabilitiesAvailable())      { @@ -1830,19 +1872,45 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe          }      } -    item_out = selected_object->getInventoryItemByAsset(func.mMaterialId); - -    LLPermissions item_permissions; -    if (item_out) +    // Look for the item to base permissions off of +    item_out = nullptr; +    if (func.mMaterialId != LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID)      { -        item_permissions.set(item_out->getPermissions()); -        for (PermissionBit op : ops) +        LLAssetIDMatchesWithPerms item_has_perms(func.mMaterialId, ops); +        if (item_source == ItemSource::OBJECT)          { -            if (!gAgent.allowOperation(op, item_permissions, GP_OBJECT_MANIPULATE)) +            item_out = selected_object->getInventoryItemByAsset(func.mMaterialId); +            if (item_out && !item_has_perms(nullptr, item_out))              {                  return false;              }          } +        else +        { +            llassert(item_source == ItemSource::AGENT); + +            LLViewerInventoryCategory::cat_array_t cats; +            LLViewerInventoryItem::item_array_t items; +            gInventory.collectDescendentsIf(LLUUID::null, +                                    cats, +                                    items, +                                    // *NOTE: PBRPickerAgentListener will need +                                    // to be changed if checking the trash is +                                    // disabled +                                    LLInventoryModel::INCLUDE_TRASH, +                                    item_has_perms); +            if (items.empty()) +            { +                return false; +            } +            item_out = items[0]; +        } +    } + +    LLPermissions item_permissions; +    if (item_out) +    { +        item_permissions = item_out->getPermissions();          // Update flags for new owner          if (!item_permissions.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true))          { @@ -1913,7 +1981,7 @@ bool LLMaterialEditor::canModifyObjectsMaterial()      LLSelectedTEGetMatData func(true);      LLPermissions permissions;      LLViewerInventoryItem* item_out; -    return can_use_objects_material(func, std::vector({PERM_MODIFY}), permissions, item_out); +    return can_use_objects_material(func, std::vector({PERM_MODIFY}), ItemSource::OBJECT, permissions, item_out);  }  bool LLMaterialEditor::canSaveObjectsMaterial() @@ -1921,7 +1989,7 @@ bool LLMaterialEditor::canSaveObjectsMaterial()      LLSelectedTEGetMatData func(true);      LLPermissions permissions;      LLViewerInventoryItem* item_out; -    return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item_out); +    return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item_out);  }  bool LLMaterialEditor::canClipboardObjectsMaterial() @@ -1947,7 +2015,7 @@ bool LLMaterialEditor::canClipboardObjectsMaterial()      LLSelectedTEGetMatData func(true);      LLPermissions permissions;      LLViewerInventoryItem* item_out; -    return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), permissions, item_out); +    return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), ItemSource::OBJECT, permissions, item_out);  }  void LLMaterialEditor::saveObjectsMaterialAs() @@ -1955,7 +2023,7 @@ void LLMaterialEditor::saveObjectsMaterialAs()      LLSelectedTEGetMatData func(true);      LLPermissions permissions;      LLViewerInventoryItem* item = nullptr; -    bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item); +    bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item);      if (!allowed)      {          LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 9150b89de3..02c00e7f87 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1880,15 +1880,55 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)  	}  } +// One-off listener that updates the build floater UI when the agent inventory adds or removes an item +class PBRPickerAgentListener : public LLInventoryObserver +{ +protected: +    bool mChangePending = true; +public: +	PBRPickerAgentListener() : LLInventoryObserver() +    { +        gInventory.addObserver(this); +    } + +    const bool isListening() +    { +        return mChangePending; +    } + +	void changed(U32 mask) override +    { +        if (!(mask & (ADD | REMOVE))) +        { +            return; +        } + +        if (gFloaterTools) +        { +            gFloaterTools->dirty(); +        } +        gInventory.removeObserver(this); +        mChangePending = false; +    } + +    ~PBRPickerAgentListener() override +    { +        gInventory.removeObserver(this); +        mChangePending = false; + +        LLInventoryObserver::~LLInventoryObserver(); +    } +}; +  // One-off listener that updates the build floater UI when the prim inventory updates -class PBRPickerItemListener : public LLVOInventoryListener +class PBRPickerObjectListener : public LLVOInventoryListener  {  protected:      LLViewerObject* mObjectp;      bool mChangePending = true;  public: -    PBRPickerItemListener(LLViewerObject* object) +    PBRPickerObjectListener(LLViewerObject* object)      : mObjectp(object)      {          registerVOInventoryListener(mObjectp, nullptr); @@ -1912,7 +1952,7 @@ public:          mChangePending = false;      } -    ~PBRPickerItemListener() +    ~PBRPickerObjectListener()      {          removeVOInventoryListener();          mChangePending = false; @@ -1931,9 +1971,9 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,      // pbr material      LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control"); +    LLUUID pbr_id;      if (pbr_ctrl)      { -        LLUUID pbr_id;          LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr, has_pbr_material, has_faces_without_pbr);          pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE); @@ -1956,14 +1996,25 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,      if (objectp->isInventoryPending())      {          // Reuse the same listener when possible -        if (!mInventoryListener || !mInventoryListener->isListeningFor(objectp)) +        if (!mVOInventoryListener || !mVOInventoryListener->isListeningFor(objectp))          { -            mInventoryListener = std::make_unique<PBRPickerItemListener>(objectp); +            mVOInventoryListener = std::make_unique<PBRPickerObjectListener>(objectp);          }      }      else      { -        mInventoryListener = nullptr; +        mVOInventoryListener = nullptr; +    } +    if (!identical_pbr || pbr_id.isNull() || pbr_id == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID) +    { +        mAgentInventoryListener = nullptr; +    } +    else +    { +        if (!mAgentInventoryListener || !mAgentInventoryListener->isListening()) +        { +            mAgentInventoryListener = std::make_unique<PBRPickerAgentListener>(); +        }      }      const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled(); diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index d36662c11b..5ca6a95699 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -53,7 +53,8 @@ class LLMaterialID;  class LLMediaCtrl;  class LLMenuButton; -class PBRPickerItemListener; +class PBRPickerAgentListener; +class PBRPickerObjectListener;  // Represents an edit for use in replicating the op across one or more materials in the selection set.  // @@ -508,7 +509,8 @@ private:      static Selection sMaterialOverrideSelection; -    std::unique_ptr<PBRPickerItemListener> mInventoryListener; +    std::unique_ptr<PBRPickerAgentListener> mAgentInventoryListener; +    std::unique_ptr<PBRPickerObjectListener> mVOInventoryListener;  public:  	#if defined(DEF_GET_MAT_STATE) | 
