diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 924c3d6d98..ad921e6c31 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -971,7 +971,17 @@ void LLFolderViewItem::draw() } drawLabel(font, text_left, y, color, right_x); - // Special for protected items + // 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); + } + // + + // FIRE-29342: Protect folder option if (mViewModelItem->isProtected()) { static const std::string protected_string = " (" + LLTrans::getString("ProtectedFolder") + ") "; diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 4a41c3a53d..cbd0cd8d46 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -224,7 +224,10 @@ public: // virtual LLFolderViewModelItem* getParent() const = 0; - // Special for protected items + // Special for locked items + virtual bool isLocked() const { return false; } + + // FIRE-29342: Protect folder option virtual bool isProtected() const { return false; } protected: diff --git a/indra/newview/aoengine.cpp b/indra/newview/aoengine.cpp index 8184e254fe..37123fc828 100644 --- a/indra/newview/aoengine.cpp +++ b/indra/newview/aoengine.cpp @@ -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() diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 2f9e2505de..e7e7fa96a0 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -744,7 +744,7 @@ Value 0 - ProtectAOFolders + LockAOFolders Comment Keep the AO folders in Inventory safe from manual changes. @@ -769,7 +769,7 @@ 0 - ProtectBridgeFolder + LockBridgeFolder Comment Keep the Bridge folder in Inventory safe from manual changes. @@ -778,7 +778,7 @@ Value 1 - ProtectWearableFavoritesFolders + LockWearableFavoritesFolders Comment Keep the Wearable Favorites folder in Inventory safe from manual changes. @@ -1279,5 +1279,16 @@ Value 0 + FSProtectedFolders + + Comment + A list of folder UUIDs that are protected from moving and deleting. + Persist + 1 + Type + LLSD + Value + + diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0f34bd9d8f..ada1cae47c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -337,8 +337,8 @@ BOOL LLInvFVBridge::isItemRemovable() const // Can be moved to another folder BOOL LLInvFVBridge::isItemMovable() const { - // FIRE-28977: Protect special and protected folders from being DaD'ed - if (isProtectedFolder()) + // 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")); - // Protected folder + // 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()) // { disabled_items.push_back(std::string("Rename")); @@ -928,7 +928,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, //if (!isCOFFolder() && !isInboxFolder() if (!isCOFFolder() // Client LSL Bridge (also for #AO) - && !isProtectedFolder()) + && !isLockedFolder()) // { items.push_back(std::string("Paste")); @@ -940,7 +940,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (gSavedSettings.getBOOL("InventoryLinking") // Client LSL Bridge (also for #AO) - && !isProtectedFolder() + && !isLockedFolder() // ) { @@ -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 } // 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; - // FIRE-28977: Protect special and protected folders from being DaD'ed - if (obj->getName() == ROOT_FIRESTORM_FOLDER || obj->getName() == RLV_ROOT_FOLDER || isProtectedFolder()) + // 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; + } + // + + // FIRE-29342: Protect folder option + if (isProtected()) { return FALSE; } @@ -2544,6 +2551,13 @@ BOOL LLFolderBridge::isItemRemovable() const return FALSE; } + // FIRE-29342: Protected folder option + if (isProtected()) + { + return FALSE; + } + // + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewFolder* folderp = dynamic_cast(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 // Client LSL Bridge (also for #AO) - if (isProtectedFolder()) return FALSE; + if (isLockedFolder()) return FALSE; // 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))); } + // 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); + } + // } 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() // moved from buildContextMenu after merge - && !isProtectedFolder() + && !isLockedFolder() // ) // do not allow creating in library { @@ -4567,7 +4602,26 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items } } - + // 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"))); + } + } + } + } + // // 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) } } +// 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; +} +// // +=================================================+ // | LLMarketplaceFolderBridge | @@ -5354,7 +5421,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if (!isAgentInventory()) return FALSE; // cannot drag into library if (!isAgentAvatarValid()) return FALSE; // Client LSL Bridge (also for #AO) - if (isProtectedFolder()) return FALSE; + if (isLockedFolder()) return FALSE; // LLInventoryPanel* destination_panel = mInventoryPanel.get(); @@ -5859,16 +5926,16 @@ bool check_item(const LLUUID& item_id, #endif // 0 // Unused 2013.10.12 -// Special for protected folders -bool LLFolderBridge::isProtected() const +// Special for locked folders +bool LLFolderBridge::isLocked() const { - static LLCachedControl protectAOFolders(gSavedPerAccountSettings, "ProtectAOFolders"); - static LLCachedControl protectBridgeFolder(gSavedPerAccountSettings, "ProtectBridgeFolder"); - static LLCachedControl WearableFavoritesprotectBridgeFolder(gSavedPerAccountSettings, "ProtectWearableFavoritesFolders"); + static LLCachedControl LockAOFolders(gSavedPerAccountSettings, "LockAOFolders"); + static LLCachedControl LockBridgeFolder(gSavedPerAccountSettings, "LockBridgeFolder"); + static LLCachedControl 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)); } // diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 36fc906635..0dd4767468 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -182,7 +182,7 @@ protected: BOOL isLostInventory() const; // [/SL:KB] // Client LSL Bridge - BOOL isProtectedFolder(bool ignore_setting = false) const; + BOOL isLockedFolder(bool ignore_setting = false) const; // virtual BOOL isItemPermissive() const; @@ -350,7 +350,10 @@ public: bool isLoading() { return mIsLoading; } - // Special for protected folders + // Special for locked folders + virtual bool isLocked() const; + + // FIRE-29342: Protect folder option virtual bool isProtected() const; protected: diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 17c315dcf7..111edeb7e0 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -643,21 +643,21 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id) return FALSE; } - // Protected Folders + // 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; } - // Protected Folders + // 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] - // Protected Folders + // 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; } - // Protected Folders + // Locked Folders if (!isAgentAvatarValid()) return FALSE; @@ -771,21 +771,21 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) } // [/RLVa:KB] - // Protected Folders + // 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; } - // Protected Folders + // 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; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 355a997e78..a26e9f6e3c 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -167,6 +167,7 @@ LLInventoryModel::LLInventoryModel() mModifyMask(LLInventoryObserver::ALL), mChangedItemIDs(), mObservers(), + mProtectedCategoriesChangedCallbackConnection(), // FIRE-29342: Protect folder option mHttpRequestFG(NULL), mHttpRequestBG(NULL), mHttpOptions(), @@ -187,6 +188,13 @@ LLInventoryModel::LLInventoryModel() LLInventoryModel::~LLInventoryModel() { cleanupInventory(); + + // FIRE-29342: Protect folder option + if (mProtectedCategoriesChangedCallbackConnection.connected()) + { + mProtectedCategoriesChangedCallbackConnection.disconnect(); + } + // } void LLInventoryModel::cleanupInventory() @@ -1353,13 +1361,13 @@ void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item, << ") from " << item->getParentUUID() << " to folder " << new_parent_id << LL_ENDL; - // Protected folder + // 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, // 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; + + // FIRE-29342: Lock folder option + mProtectedCategoriesChangedCallbackConnection = gSavedPerAccountSettings.getControl("FSProtectedFolders")->getCommitSignal()->connect(boost::bind(&LLInventoryModel::onProtectedCategoriesChanged, this, _2)); + onProtectedCategoriesChanged(gSavedPerAccountSettings.getLLSD("FSProtectedFolders")); + // } const LLUUID &LLInventoryModel::getLibraryRootFolderID() const @@ -4043,6 +4056,18 @@ void LLInventoryModel::wearItemsOnAvatar(LLInventoryCategory* category) } // +// 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); + } +} +// + class LLViewerInventoryItemSort { public: diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 9cc1c33fad..7a8fca8875 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -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); -// ReplaceWornItemsOnly + // ReplaceWornItemsOnly void wearItemsOnAvatar(LLInventoryCategory* category); void wearAttachmentsOnAvatarCheckRemove(LLViewerObject *object, const LLViewerJointAttachment *attachment); + // + + // FIRE-29342: Protect folder option + const uuid_set_t& getProtectedCategories() const { return mProtectedCategories; }; private: + mutable LLPointer mLastItem; // cache recent lookups + + // ReplaceWornItemsOnly void wearWearablesOnAvatar(const LLUUID& category_id); void wearAttachmentsOnAvatar(const LLUUID& category_id); void wearGesturesOnAvatar(const LLUUID& category_id); -// -private: - mutable LLPointer mLastItem; // cache recent lookups + // + + // FIRE-29342: Protect folder option + uuid_set_t mProtectedCategories; + boost::signals2::connection mProtectedCategoriesChangedCallbackConnection; + void onProtectedCategoriesChanged(const LLSD& newvalue); + // //-------------------------------------------------------------------- // Count diff --git a/indra/newview/skins/default/xui/de/menu_inventory.xml b/indra/newview/skins/default/xui/de/menu_inventory.xml index f1af6dc732..57d9b032c7 100644 --- a/indra/newview/skins/default/xui/de/menu_inventory.xml +++ b/indra/newview/skins/default/xui/de/menu_inventory.xml @@ -76,6 +76,8 @@ + + diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 13eef83a7d..5d576d504c 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -798,6 +798,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. Wird geladen... + + gesperrt + geschützt diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 04e191ff08..43f271fb12 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -569,6 +569,22 @@ function="Inventory.DoToSelected" parameter="rename" /> + + + + + + Loading... - + + locked protected - (nobody)