diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index b08c6fd21a..ce64ba2c9a 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3540,6 +3540,15 @@ void LLFolderBridge::perform_pasteFromClipboard()
LLNotificationsUtil::add("StockPasteFailed", subs);
return;
}
+
+// [RLVa:KB] - Checked: RLVa-2.1.0
+ if ( ((item) && (!RlvActions::canPaste(item, dest_folder))) || ((cat) && (!RlvActions::canPaste(cat, dest_folder))) )
+ {
+ RlvActions::notifyBlocked(RLV_STRING_BLOCKED_INVFOLDER);
+ return;
+ }
+// [/RLVa:KB]
+
}
}
diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp
index b41302b5bf..b4fd076b06 100644
--- a/indra/newview/rlvactions.cpp
+++ b/indra/newview/rlvactions.cpp
@@ -23,6 +23,7 @@
#include "rlvactions.h"
#include "rlvhelper.h"
#include "rlvhandler.h"
+#include "rlvinventory.h"
// ============================================================================
// Camera
@@ -216,6 +217,26 @@ bool RlvActions::canShowNearbyAgents()
return !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNEARBY);
}
+// ============================================================================
+// Inventory
+//
+
+bool RlvActions::canPaste(const LLInventoryCategory* pSourceCat, const LLInventoryCategory* pDestCat)
+{
+ // The user can paste the specified object into the destination if:
+ // - the source and destination are subject to the same lock type (or none at all) => NOTE: this happens to be the same logic we use for moving
+ return (isRlvEnabled()) && (pSourceCat) && (pDestCat) &&
+ ((!RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().canMoveFolder(pSourceCat->getUUID(), pDestCat->getUUID())));
+}
+
+bool RlvActions::canPaste(const LLInventoryItem* pSourceItem, const LLInventoryCategory* pDestCat)
+{
+ // The user can paste the specified object into the destination if:
+ // - the source and destination are subject to the same lock type (or none at all) => NOTE: this happens to be the same logic we use for moving
+ return (isRlvEnabled()) && (pSourceItem) && (pDestCat) &&
+ ((!RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().canMoveItem(pSourceItem->getUUID(), pDestCat->getUUID())));
+}
+
// ============================================================================
// Movement
//
@@ -386,4 +407,9 @@ bool RlvActions::isRlvEnabled()
return RlvHandler::isEnabled();
}
+void RlvActions::notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs)
+{
+ RlvUtil::notifyBlocked(strNotifcation, sdArgs);
+}
+
// ============================================================================
diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h
index 6b21087635..51fa36b613 100644
--- a/indra/newview/rlvactions.h
+++ b/indra/newview/rlvactions.h
@@ -19,6 +19,13 @@
#include "rlvdefines.h"
+// ============================================================================
+// Forward declarations
+//
+
+class LLInventoryCategory;
+class LLInventoryItem;
+
// ============================================================================
// RlvActions class declaration - developer-friendly non-RLVa code facing class, use in lieu of RlvHandler whenever possible
//
@@ -122,6 +129,16 @@ protected:
// Backwards logic so that we can initialize to 0 and it won't block when we forget to/don't check if RLVa is disabled
static bool s_BlockNamesContexts[SNC_COUNT];
+ // =========
+ // Inventory
+ // =========
+public:
+ /*
+ * Returns true if the user is allowed to paste the specified inventory object (item/folder) into the specified destination category (within user inventory)
+ */
+ static bool canPaste(const LLInventoryCategory* pSourceCat, const LLInventoryCategory* pDestCat);
+ static bool canPaste(const LLInventoryItem* pSourceItem, const LLInventoryCategory* pDestCat);
+
// ========
// Movement
// ========
@@ -232,6 +249,11 @@ public:
* Convenience function to check if RLVa is enabled without having to include rlvhandler.h
*/
static bool isRlvEnabled();
+
+ /*
+ * Shows one of the blocked toast notifications (see rlva_strings.xml)
+ */
+ static void notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs = LLSD());
};
// ============================================================================
diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h
index 9c150b9136..fbb21ea77c 100644
--- a/indra/newview/rlvdefines.h
+++ b/indra/newview/rlvdefines.h
@@ -374,6 +374,7 @@ enum ERlvAttachGroupType
#define RLV_STRING_BLOCKED_AUTOPILOT "blocked_autopilot"
#define RLV_STRING_BLOCKED_GENERIC "blocked_generic"
#define RLV_STRING_BLOCKED_GROUPCHANGE "blocked_groupchange"
+#define RLV_STRING_BLOCKED_INVFOLDER "blocked_invfolder"
#define RLV_STRING_BLOCKED_PERMATTACH "blocked_permattach"
#define RLV_STRING_BLOCKED_PERMTELEPORT "blocked_permteleport"
#define RLV_STRING_BLOCKED_RECVIM "blocked_recvim"
diff --git a/indra/newview/skins/default/xui/en/rlva_strings.xml b/indra/newview/skins/default/xui/en/rlva_strings.xml
index 922173282b..5f6a92c35f 100644
--- a/indra/newview/skins/default/xui/en/rlva_strings.xml
+++ b/indra/newview/skins/default/xui/en/rlva_strings.xml
@@ -61,6 +61,11 @@
value
Unable to change your active group due to an RLV restriction; switching back to [GROUP_SLURL]
+ blocked_invfolder
+
blocked_nearby