FIRE-20414 / FIRE-29342: Add option to protect folders from getting moved or deleted

meow-7.2.2
Ansariel 2020-04-14 17:03:26 +02:00
parent be671fba7b
commit 22ac7edd6e
13 changed files with 232 additions and 81 deletions

View File

@ -971,7 +971,17 @@ void LLFolderViewItem::draw()
}
drawLabel(font, text_left, y, color, right_x);
// <FS:Ansariel> Special for protected items
// <FS:Ansariel> Special for locked items
if (mViewModelItem->isLocked())
{
static const std::string locked_string = " (" + LLTrans::getString("LockedFolder") + ") ";
font->renderUTF8(locked_string, 0, right_x, y, sProtectedColor,
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
S32_MAX, S32_MAX, &right_x, FALSE);
}
// </FS:Ansariel>
// <FS:Ansariel> FIRE-29342: Protect folder option
if (mViewModelItem->isProtected())
{
static const std::string protected_string = " (" + LLTrans::getString("ProtectedFolder") + ") ";

View File

@ -224,7 +224,10 @@ public:
// <FS:ND/>
virtual LLFolderViewModelItem* getParent() const = 0;
// <FS:Ansariel> Special for protected items
// <FS:Ansariel> Special for locked items
virtual bool isLocked() const { return false; }
// <FS:Ansariel> FIRE-29342: Protect folder option
virtual bool isProtected() const { return false; }
protected:

View File

@ -963,11 +963,11 @@ LLUUID AOEngine::addSet(const std::string& name, BOOL reload)
return LLUUID::null;
}
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("ProtectAOFolders");
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", FALSE);
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders");
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
LL_DEBUGS("AOEngine") << "adding set folder " << name << LL_ENDL;
LLUUID newUUID = gInventory.createNewCategory(mAOFolder, LLFolderType::FT_NONE, name);
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", wasProtected);
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
if (reload)
{
@ -1030,10 +1030,10 @@ BOOL AOEngine::addAnimation(const AOSet* set, AOSet::AOState* state, const LLInv
anim.mSortOrder = state->mAnimations.size() + 1;
state->mAnimations.push_back(anim);
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("ProtectAOFolders");
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", FALSE);
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders");
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
createAnimationLink(set, state, item);
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", wasProtected);
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
if (reload)
{
@ -1060,8 +1060,8 @@ BOOL AOEngine::findForeignItems(const LLUUID& uuid) const
}
// count backwards in case we have to remove items
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("ProtectAOFolders");
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", FALSE);
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders");
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
for (S32 index = items->size() - 1; index >= 0; --index)
{
BOOL move = FALSE;
@ -1093,7 +1093,7 @@ BOOL AOEngine::findForeignItems(const LLUUID& uuid) const
LL_DEBUGS("AOEngine") << item->getName() << " moved to lost and found!" << LL_ENDL;
}
}
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", wasProtected);
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
return moved;
}
@ -1102,8 +1102,8 @@ BOOL AOEngine::findForeignItems(const LLUUID& uuid) const
void AOEngine::purgeFolder(const LLUUID& uuid) const
{
// unprotect it
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("ProtectAOFolders");
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", FALSE);
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders");
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
// move everything that's not an animation link to "lost and found"
if (findForeignItems(uuid))
@ -1123,7 +1123,7 @@ void AOEngine::purgeFolder(const LLUUID& uuid) const
gInventory.notifyObservers();
// protect it
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", wasProtected);
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
}
BOOL AOEngine::removeSet(AOSet* set)
@ -1601,10 +1601,10 @@ void AOEngine::saveSet(const AOSet* set)
gInventory.addChangedMask(LLInventoryObserver::LABEL, cat->getUUID());
gInventory.notifyObservers();
*/
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("ProtectAOFolders");
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", FALSE);
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders");
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
rename_category(&gInventory, set->getInventoryUUID(), setParams);
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", wasProtected);
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
LL_INFOS("AOEngine") << "sending update signal" << LL_ENDL;
mUpdatedSignal();
@ -1641,10 +1641,10 @@ void AOEngine::saveState(const AOSet::AOState* state)
stateParams += ":RN";
}
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("ProtectAOFolders");
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", FALSE);
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders");
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
rename_category(&gInventory, state->mInventoryUUID, stateParams);
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", wasProtected);
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
}
void AOEngine::saveSettings()

View File

@ -744,7 +744,7 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>ProtectAOFolders</key>
<key>LockAOFolders</key>
<map>
<key>Comment</key>
<string>Keep the AO folders in Inventory safe from manual changes.</string>
@ -769,7 +769,7 @@
<integer>0</integer>
</array>
</map>
<key>ProtectBridgeFolder</key>
<key>LockBridgeFolder</key>
<map>
<key>Comment</key>
<string>Keep the Bridge folder in Inventory safe from manual changes.</string>
@ -778,7 +778,7 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>ProtectWearableFavoritesFolders</key>
<key>LockWearableFavoritesFolders</key>
<map>
<key>Comment</key>
<string>Keep the Wearable Favorites folder in Inventory safe from manual changes.</string>
@ -1279,5 +1279,16 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>FSProtectedFolders</key>
<map>
<key>Comment</key>
<string>A list of folder UUIDs that are protected from moving and deleting.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>LLSD</string>
<key>Value</key>
<array/>
</map>
</map>
</llsd>

View File

@ -337,8 +337,8 @@ BOOL LLInvFVBridge::isItemRemovable() const
// Can be moved to another folder
BOOL LLInvFVBridge::isItemMovable() const
{
// <FS:Ansariel> FIRE-28977: Protect special and protected folders from being DaD'ed
if (isProtectedFolder())
// <FS:Ansariel> FIRE-28977: Lock special and locked folders from being DaD'ed
if (isLockedFolder())
{
// Child of a protected folder -> not movable
return FALSE;
@ -868,9 +868,9 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if (!isInboxFolder())
{
items.push_back(std::string("Rename"));
// <FS> Protected folder
// <FS> Locked folder
//if (!isItemRenameable() || ((flags & FIRST_SELECTED_ITEM) == 0))
if (!isItemRenameable() || ((flags & FIRST_SELECTED_ITEM) == 0) || isProtectedFolder())
if (!isItemRenameable() || ((flags & FIRST_SELECTED_ITEM) == 0) || isLockedFolder())
// </FS>
{
disabled_items.push_back(std::string("Rename"));
@ -928,7 +928,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
//if (!isCOFFolder() && !isInboxFolder()
if (!isCOFFolder()
// <FS:TT> Client LSL Bridge (also for #AO)
&& !isProtectedFolder())
&& !isLockedFolder())
// </FS:TT>
{
items.push_back(std::string("Paste"));
@ -940,7 +940,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if (gSavedSettings.getBOOL("InventoryLinking")
// <FS:TT> Client LSL Bridge (also for #AO)
&& !isProtectedFolder()
&& !isLockedFolder()
// </FS:TT>
)
{
@ -1231,7 +1231,7 @@ void LLInvFVBridge::addMoveToDefaultFolderMenuOption(menuentry_vec_t& items)
{
const LLInventoryObject* obj = getInventoryObject();
if (isAgentInventory() && !isProtectedFolder(true) && obj &&
if (isAgentInventory() && !isLockedFolder(true) && obj &&
obj->getActualType() != LLAssetType::AT_CATEGORY &&
obj->getActualType() != LLAssetType::AT_LINK_FOLDER &&
obj->getActualType() != LLAssetType::AT_LINK &&
@ -1362,7 +1362,7 @@ BOOL LLInvFVBridge::isCOFFolder() const
}
// <FS:TT> Client LSL Bridge (also for #AO)
BOOL LLInvFVBridge::isProtectedFolder(bool ignore_setting /*= false*/) const
BOOL LLInvFVBridge::isLockedFolder(bool ignore_setting /*= false*/) const
{
const LLInventoryModel* model = getInventoryModel();
if (!model)
@ -1372,21 +1372,21 @@ BOOL LLInvFVBridge::isProtectedFolder(bool ignore_setting /*= false*/) const
if ((mUUID == FSLSLBridge::instance().getBridgeFolder()
|| model->isObjectDescendentOf(mUUID, FSLSLBridge::instance().getBridgeFolder()))
&& (gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder") || ignore_setting))
&& (gSavedPerAccountSettings.getBOOL("LockBridgeFolder") || ignore_setting))
{
return TRUE;
}
if ((mUUID == AOEngine::instance().getAOFolder()
|| model->isObjectDescendentOf(mUUID, AOEngine::instance().getAOFolder()))
&& (gSavedPerAccountSettings.getBOOL("ProtectAOFolders") || ignore_setting))
&& (gSavedPerAccountSettings.getBOOL("LockAOFolders") || ignore_setting))
{
return TRUE;
}
if ((mUUID == FSFloaterWearableFavorites::getFavoritesFolder()
|| model->isObjectDescendentOf(mUUID, FSFloaterWearableFavorites::getFavoritesFolder()))
&& gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders"))
&& gSavedPerAccountSettings.getBOOL("LockWearableFavoritesFolders"))
{
return TRUE;
}
@ -2393,8 +2393,15 @@ BOOL LLFolderBridge::isItemMovable() const
if (LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType()))
return FALSE;
// <FS:Ansariel> FIRE-28977: Protect special and protected folders from being DaD'ed
if (obj->getName() == ROOT_FIRESTORM_FOLDER || obj->getName() == RLV_ROOT_FOLDER || isProtectedFolder())
// <FS:Ansariel> FIRE-28977: Lock special and locked folders from being DaD'ed
if (obj->getName() == ROOT_FIRESTORM_FOLDER || obj->getName() == RLV_ROOT_FOLDER || isLockedFolder())
{
return FALSE;
}
// </FS:Ansariel>
// <FS:Ansariel> FIRE-29342: Protect folder option
if (isProtected())
{
return FALSE;
}
@ -2544,6 +2551,13 @@ BOOL LLFolderBridge::isItemRemovable() const
return FALSE;
}
// <FS:Ansariel> FIRE-29342: Protected folder option
if (isProtected())
{
return FALSE;
}
// </FS:Ansariel>
LLInventoryPanel* panel = mInventoryPanel.get();
LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getItemByID(mUUID) : NULL);
if (folderp)
@ -2718,7 +2732,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
if (!isAgentAvatarValid()) return FALSE;
if (!isAgentInventory()) return FALSE; // cannot drag categories into library
// <FS:TT> Client LSL Bridge (also for #AO)
if (isProtectedFolder()) return FALSE;
if (isLockedFolder()) return FALSE;
// </FS:TT>
LLInventoryPanel* destination_panel = mInventoryPanel.get();
@ -3689,6 +3703,27 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
move_folder_to_marketplacelistings(cat, marketplacelistings_id, ("move_to_marketplace_listings" != action), (("copy_or_move_to_marketplace_listings" == action)));
}
// <FS:Ansariel> FIRE-29342: Protect folder option
else if ("protect_folder" == action)
{
LLSD protected_folders = gSavedPerAccountSettings.getLLSD("FSProtectedFolders");
protected_folders.append(mUUID);
gSavedPerAccountSettings.setLLSD("FSProtectedFolders", protected_folders);
}
else if ("unprotect_folder" == action)
{
LLSD protected_folders = gSavedPerAccountSettings.getLLSD("FSProtectedFolders");
LLSD new_protected_folders;
for (LLSD::array_const_iterator it = protected_folders.beginArray(); it != protected_folders.endArray(); ++it)
{
if ((*it).asUUID() != mUUID)
{
new_protected_folders.append(*it);
}
}
gSavedPerAccountSettings.setLLSD("FSProtectedFolders", new_protected_folders);
}
// </FS:Ansariel>
}
void LLFolderBridge::gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level)
@ -4432,7 +4467,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
else if(isAgentInventory()
// <FS:ND> moved from buildContextMenu after merge
&& !isProtectedFolder()
&& !isLockedFolder()
// </FS:ND>
) // do not allow creating in library
{
@ -4567,7 +4602,26 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
}
// <FS:Ansariel> FIRE-29342: Protect folder option
if (isAgentInventory())
{
LLInventoryObject* obj = getInventoryObject();
if (obj)
{
if (!LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType()))
{
if (isProtected())
{
items.push_back((std::string("UnprotectFolder")));
}
else
{
items.push_back((std::string("ProtectFolder")));
}
}
}
}
// </FS:Ansariel>
// Add menu items that are dependent on the contents of the folder.
LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
@ -4965,6 +5019,19 @@ void LLFolderBridge::modifyOutfit(BOOL append)
}
}
// <FS:Ansariel> FIRE-29342: Protect folder option
bool LLFolderBridge::isProtected() const
{
LLInventoryModel* model = getInventoryModel();
if (model)
{
const uuid_set_t& categories = model->getProtectedCategories();
return categories.find(mUUID) != categories.end();
}
return false;
}
// </FS:Ansariel>
// +=================================================+
// | LLMarketplaceFolderBridge |
@ -5354,7 +5421,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
if (!isAgentInventory()) return FALSE; // cannot drag into library
if (!isAgentAvatarValid()) return FALSE;
// <FS:TT> Client LSL Bridge (also for #AO)
if (isProtectedFolder()) return FALSE;
if (isLockedFolder()) return FALSE;
// </FS:TT>
LLInventoryPanel* destination_panel = mInventoryPanel.get();
@ -5859,16 +5926,16 @@ bool check_item(const LLUUID& item_id,
#endif // 0
// <FS:CR> Unused 2013.10.12
// <FS:Ansariel> Special for protected folders
bool LLFolderBridge::isProtected() const
// <FS:Ansariel> Special for locked folders
bool LLFolderBridge::isLocked() const
{
static LLCachedControl<bool> protectAOFolders(gSavedPerAccountSettings, "ProtectAOFolders");
static LLCachedControl<bool> protectBridgeFolder(gSavedPerAccountSettings, "ProtectBridgeFolder");
static LLCachedControl<bool> WearableFavoritesprotectBridgeFolder(gSavedPerAccountSettings, "ProtectWearableFavoritesFolders");
static LLCachedControl<bool> LockAOFolders(gSavedPerAccountSettings, "LockAOFolders");
static LLCachedControl<bool> LockBridgeFolder(gSavedPerAccountSettings, "LockBridgeFolder");
static LLCachedControl<bool> LockWearableFavoritesFolders(gSavedPerAccountSettings, "LockWearableFavoritesFolders");
return ((mUUID == AOEngine::instance().getAOFolder() && protectAOFolders) ||
(mUUID == FSLSLBridge::instance().getBridgeFolder() && protectBridgeFolder) ||
(mUUID == FSFloaterWearableFavorites::getFavoritesFolder() && WearableFavoritesprotectBridgeFolder));
return ((mUUID == AOEngine::instance().getAOFolder() && LockAOFolders) ||
(mUUID == FSLSLBridge::instance().getBridgeFolder() && LockBridgeFolder) ||
(mUUID == FSFloaterWearableFavorites::getFavoritesFolder() && LockWearableFavoritesFolders));
}
// </FS:Ansariel>

View File

@ -182,7 +182,7 @@ protected:
BOOL isLostInventory() const;
// [/SL:KB]
// <FS:TT> Client LSL Bridge
BOOL isProtectedFolder(bool ignore_setting = false) const;
BOOL isLockedFolder(bool ignore_setting = false) const;
// </FS:TT>
virtual BOOL isItemPermissive() const;
@ -350,7 +350,10 @@ public:
bool isLoading() { return mIsLoading; }
// <FS:Ansariel> Special for protected folders
// <FS:Ansariel> Special for locked folders
virtual bool isLocked() const;
// <FS:Ansariel> FIRE-29342: Protect folder option
virtual bool isProtected() const;
protected:

View File

@ -643,21 +643,21 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
return FALSE;
}
// <FS> Protected Folders
// <FS> Locked Folders
if (
(model->isObjectDescendentOf(id, AOEngine::instance().getAOFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectAOFolders"))
&& gSavedPerAccountSettings.getBOOL("LockAOFolders"))
||
(model->isObjectDescendentOf(id, FSLSLBridge::instance().getBridgeFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder"))
&& gSavedPerAccountSettings.getBOOL("LockBridgeFolder"))
||
(model->isObjectDescendentOf(id, FSFloaterWearableFavorites::getFavoritesFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders"))
&& gSavedPerAccountSettings.getBOOL("LockWearableFavoritesFolders"))
)
{
return FALSE;
}
// </FS> Protected Folders
// </FS> Locked Folders
// 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).
@ -713,21 +713,21 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
}
// [/RLVa:KB]
// <FS> Protected Folders
// <FS> Locked Folders
if (
((id == AOEngine::instance().getAOFolder() || model->isObjectDescendentOf(id, AOEngine::instance().getAOFolder()))
&& gSavedPerAccountSettings.getBOOL("ProtectAOFolders"))
&& gSavedPerAccountSettings.getBOOL("LockAOFolders"))
||
((id == FSLSLBridge::instance().getBridgeFolder() || model->isObjectDescendentOf(id, FSLSLBridge::instance().getBridgeFolder()))
&& gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder"))
&& gSavedPerAccountSettings.getBOOL("LockBridgeFolder"))
||
((id == FSFloaterWearableFavorites::getFavoritesFolder() || model->isObjectDescendentOf(id, FSFloaterWearableFavorites::getFavoritesFolder()))
&& gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders"))
&& gSavedPerAccountSettings.getBOOL("LockWearableFavoritesFolders"))
)
{
return FALSE;
}
// </FS> Protected Folders
// </FS> Locked Folders
if (!isAgentAvatarValid()) return FALSE;
@ -771,21 +771,21 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
}
// [/RLVa:KB]
// <FS> Protected Folders
// <FS> Locked Folders
if (
((id == AOEngine::instance().getAOFolder() || model->isObjectDescendentOf(id, AOEngine::instance().getAOFolder()))
&& gSavedPerAccountSettings.getBOOL("ProtectAOFolders"))
&& gSavedPerAccountSettings.getBOOL("LockAOFolders"))
||
((id == FSLSLBridge::instance().getBridgeFolder() || model->isObjectDescendentOf(id, FSLSLBridge::instance().getBridgeFolder()))
&& gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder"))
&& gSavedPerAccountSettings.getBOOL("LockBridgeFolder"))
||
((id == FSFloaterWearableFavorites::getFavoritesFolder() || model->isObjectDescendentOf(id, FSFloaterWearableFavorites::getFavoritesFolder()))
&& gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders"))
&& gSavedPerAccountSettings.getBOOL("LockWearableFavoritesFolders"))
)
{
return FALSE;
}
// </FS> Protected Folders
// </FS> Locked Folders
LLViewerInventoryCategory* cat = model->getCategory(id);
@ -2611,8 +2611,8 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
model->collectDescendents(obj->getUUID(), cats, items, FALSE);
LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
BOOL old_setting = gSavedPerAccountSettings.getBOOL("ProtectAOFolders");
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", FALSE);
BOOL old_setting = gSavedPerAccountSettings.getBOOL("LockAOFolders");
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
if ((*it)->getIsLinkType() && LLAssetType::lookupIsLinkType((*it)->getType()))
@ -2620,7 +2620,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
model->removeItem((*it)->getUUID());
}
}
gSavedPerAccountSettings.setBOOL("ProtectAOFolders", old_setting);
gSavedPerAccountSettings.setBOOL("LockAOFolders", old_setting);
}
}
return;

View File

@ -167,6 +167,7 @@ LLInventoryModel::LLInventoryModel()
mModifyMask(LLInventoryObserver::ALL),
mChangedItemIDs(),
mObservers(),
mProtectedCategoriesChangedCallbackConnection(), // <FS:Ansariel> FIRE-29342: Protect folder option
mHttpRequestFG(NULL),
mHttpRequestBG(NULL),
mHttpOptions(),
@ -187,6 +188,13 @@ LLInventoryModel::LLInventoryModel()
LLInventoryModel::~LLInventoryModel()
{
cleanupInventory();
// <FS:Ansariel> FIRE-29342: Protect folder option
if (mProtectedCategoriesChangedCallbackConnection.connected())
{
mProtectedCategoriesChangedCallbackConnection.disconnect();
}
// </FS:Ansariel>
}
void LLInventoryModel::cleanupInventory()
@ -1353,13 +1361,13 @@ void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item,
<< ") from " << item->getParentUUID() << " to folder "
<< new_parent_id << LL_ENDL;
// <FS> Protected folder
// <FS> Locked folder
if ((isObjectDescendentOf(item->getUUID(), AOEngine::instance().getAOFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectAOFolders")) ||
&& gSavedPerAccountSettings.getBOOL("LockAOFolders")) ||
(isObjectDescendentOf(item->getUUID(), FSLSLBridge::instance().getBridgeFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder")) ||
&& gSavedPerAccountSettings.getBOOL("LockBridgeFolder")) ||
(isObjectDescendentOf(item->getUUID(), FSFloaterWearableFavorites::getFavoritesFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders")))
&& gSavedPerAccountSettings.getBOOL("LockWearableFavoritesFolders")))
{
LL_INFOS("Inventory") << "Cannot move item because it is descendent of a protected folder" << LL_ENDL;
return;
@ -1399,11 +1407,11 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat,
// <FS> Protected folder
if ((isObjectDescendentOf(cat->getUUID(), AOEngine::instance().getAOFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectAOFolders")) ||
&& gSavedPerAccountSettings.getBOOL("LockAOFolders")) ||
(isObjectDescendentOf(cat->getUUID(), FSLSLBridge::instance().getBridgeFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder")) ||
&& gSavedPerAccountSettings.getBOOL("LockBridgeFolder")) ||
(isObjectDescendentOf(cat->getUUID(), FSFloaterWearableFavorites::getFavoritesFolder())
&& gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders")))
&& gSavedPerAccountSettings.getBOOL("LockWearableFavoritesFolders")))
{
LL_INFOS("Inventory") << "Cannot move category because it is descendent of a protected folder" << LL_ENDL;
return;
@ -3746,6 +3754,11 @@ const LLUUID &LLInventoryModel::getRootFolderID() const
void LLInventoryModel::setRootFolderID(const LLUUID& val)
{
mRootFolderID = val;
// <FS:Ansariel> FIRE-29342: Lock folder option
mProtectedCategoriesChangedCallbackConnection = gSavedPerAccountSettings.getControl("FSProtectedFolders")->getCommitSignal()->connect(boost::bind(&LLInventoryModel::onProtectedCategoriesChanged, this, _2));
onProtectedCategoriesChanged(gSavedPerAccountSettings.getLLSD("FSProtectedFolders"));
// </FS:Ansariel>
}
const LLUUID &LLInventoryModel::getLibraryRootFolderID() const
@ -4043,6 +4056,18 @@ void LLInventoryModel::wearItemsOnAvatar(LLInventoryCategory* category)
}
// </FS:TT>
// <FS:Ansariel> FIRE-29342: Protect folder option
void LLInventoryModel::onProtectedCategoriesChanged(const LLSD& newvalue)
{
mProtectedCategories.clear();
for (LLSD::array_const_iterator it = newvalue.beginArray(); it != newvalue.endArray(); ++it)
{
mProtectedCategories.insert(*it);
}
}
// </FS:Ansariel>
class LLViewerInventoryItemSort
{
public:

View File

@ -342,17 +342,28 @@ public:
// Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories
void consolidateForType(const LLUUID& id, LLFolderType::EType type);
// <FS:TT> ReplaceWornItemsOnly
// <FS:TT> ReplaceWornItemsOnly
void wearItemsOnAvatar(LLInventoryCategory* category);
void wearAttachmentsOnAvatarCheckRemove(LLViewerObject *object, const LLViewerJointAttachment *attachment);
// </FS:TT>
// <FS:Ansariel> FIRE-29342: Protect folder option
const uuid_set_t& getProtectedCategories() const { return mProtectedCategories; };
private:
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
// <FS:TT> ReplaceWornItemsOnly
void wearWearablesOnAvatar(const LLUUID& category_id);
void wearAttachmentsOnAvatar(const LLUUID& category_id);
void wearGesturesOnAvatar(const LLUUID& category_id);
// </FS:TT>
private:
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
// </FS:TT>
// <FS:Ansariel> FIRE-29342: Protect folder option
uuid_set_t mProtectedCategories;
boost::signals2::connection mProtectedCategoriesChangedCallbackConnection;
void onProtectedCategoriesChanged(const LLSD& newvalue);
// </FS:Ansariel>
//--------------------------------------------------------------------
// Count

View File

@ -76,6 +76,8 @@
<menu_item_call label="Original öffnen" name="Open Original"/>
<menu_item_call label="Eigenschaften" name="Properties"/>
<menu_item_call label="Umbenennen" name="Rename"/>
<menu_item_call label="Schützen" name="ProtectFolder"/>
<menu_item_call label="Schutz aufheben" name="UnprotectFolder"/>
<menu_item_call label="Asset-UUID kopieren" name="Copy Asset UUID"/>
<menu_item_call label="Wiederherstellen an letzter Position" name="Restore to Last Position"/>
<menu_item_call label="Ausschneiden" name="Cut"/>

View File

@ -798,6 +798,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="LoadingData">
Wird geladen...
</string>
<string name="LockedFolder">
gesperrt
</string>
<string name="ProtectedFolder">
geschützt
</string>

View File

@ -569,6 +569,22 @@
function="Inventory.DoToSelected"
parameter="rename" />
</menu_item_call>
<menu_item_call
label="Protect"
layout="topleft"
name="ProtectFolder">
<menu_item_call.on_click
function="Inventory.DoToSelected"
parameter="protect_folder" />
</menu_item_call>
<menu_item_call
label="Unprotect"
layout="topleft"
name="UnprotectFolder">
<menu_item_call.on_click
function="Inventory.DoToSelected"
parameter="unprotect_folder" />
</menu_item_call>
<menu_item_call
label="Copy Asset UUID"
layout="topleft"

View File

@ -375,10 +375,10 @@ Please try logging in again in a minute.</string>
<!-- Indicates something is being loaded. Maybe should be merged with RetrievingData -->
<string name="LoadingData">Loading...</string>
<!-- Indicates a protected Inventory folder. ## Zi: Animation Overrider -->
<!-- Indicates a locked Inventory folder. ## Zi: Animation Overrider -->
<string name="LockedFolder">locked</string>
<string name="ProtectedFolder">protected</string>
<!-- namecache -->
<!-- Avatar name: text shown for LLUUID::null -->
<string name="AvatarNameNobody">(nobody)</string>