diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c51535d7d..102738498 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1656,6 +1656,7 @@ void init_debug_rlva_menu(LLMenuGL* menu) menu->addChild(new LLMenuItemCheckGL("Restrictions...", &RlvFloaterBehaviours::toggle, NULL, &RlvFloaterBehaviours::visible, NULL)); menu->addChild(new LLMenuItemCheckGL("Locks...", &RlvFloaterLocks::toggle, NULL, &RlvFloaterLocks::visible, NULL)); + menu->addChild(new LLMenuItemCheckGL("Strings...", &RlvFloaterStrings::toggle, NULL, &RlvFloaterStrings::visible, NULL)); } // [/RLVa:KB] diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index e1184b4f4..bd4326680 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -167,16 +167,17 @@ void RlvStrings::initClass() if (!fInitialized) { // Load the default string values - std::string* itFile = &gDirUtilp->findSkinnedFilename(LLUICtrlFactory::getXUIPaths().front(), RLV_STRINGS_FILE); - /* + /* Singu TODO: findSkinnedFilenames/LLDir update std::vector files = gDirUtilp->findSkinnedFilenames(LLDir::XUI, RLV_STRINGS_FILE, LLDir::ALL_SKINS); m_StringMapPath = (!files.empty()) ? files.front() : LLStringUtil::null; for (auto itFile = files.cbegin(); itFile != files.cend(); ++itFile) */ - if (!itFile->empty()) + std::string itFile = gDirUtilp->findSkinnedFilename(LLUICtrlFactory::getXUIPaths().front(), RLV_STRINGS_FILE); + if (!itFile.empty()) { - loadFromFile(*itFile, false); + loadFromFile(itFile, false); } + m_StringMapPath = itFile; // Singu TODO: Remove this when updating to the above LLDir impl. // Load the custom string overrides loadFromFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, RLV_STRINGS_FILE), true); diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index 68f3dc2c1..d409d08ba 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -15,9 +15,16 @@ */ #include "llviewerprecompiledheaders.h" + +#include "llappearancemgr.h" #include "llavatarnamecache.h" #include "llclipboard.h" +#include "llcombobox.h" +#include "llinventoryfunctions.h" +#include "llnotificationsutil.h" #include "llscrolllistctrl.h" +#include "llsdserialize.h" +#include "lltexteditor.h" #include "llviewerjointattachment.h" #include "llviewerobjectlist.h" #include "llvoavatarself.h" @@ -32,6 +39,34 @@ // Helper functions // +// Checked: 2012-07-14 (RLVa-1.4.7) +std::string rlvGetItemName(const LLViewerInventoryItem* pItem) +{ + if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) ) + return llformat("%s (%s)", pItem->getName().c_str(), LLWearableType::getTypeName(pItem->getWearableType()).c_str()); + else if ( (pItem) && (LLAssetType::AT_OBJECT == pItem->getType()) && (isAgentAvatarValid()) ) + return llformat("%s (%s)", pItem->getName().c_str(), gAgentAvatarp->getAttachedPointName(pItem->getUUID()).c_str()); + return (pItem) ? pItem->getName() : LLStringUtil::null; +} + +// Checked: 2012-07-14 (RLVa-1.4.7) +std::string rlvGetItemType(const LLViewerInventoryItem* pItem) +{ + if (pItem) + { + switch (pItem->getType()) + { + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_CLOTHING: + return "Wearable"; + case LLAssetType::AT_OBJECT: + return "Attachment"; + default: + break; + } + } + return "Unknown"; +} // Checked: 2010-03-11 (RLVa-1.2.0a) | Modified: RLVa-1.2.0g std::string rlvGetItemNameFromObjID(const LLUUID& idObj, bool fIncludeAttachPt = true) @@ -61,13 +96,97 @@ bool rlvGetShowException(ERlvBehaviour eBhvr) case RLV_BHVR_RECVIM: case RLV_BHVR_STARTIM: case RLV_BHVR_TPLURE: + case RLV_BHVR_TPREQUEST: case RLV_BHVR_ACCEPTTP: + case RLV_BHVR_ACCEPTTPREQUEST: return true; default: return false; } } +// Checked: 2012-07-29 (RLVa-1.4.7) +std::string rlvLockMaskToString(ERlvLockMask eLockType) +{ + switch (eLockType) + { + case RLV_LOCK_ADD: + return "add"; + case RLV_LOCK_REMOVE: + return "rem"; + default: + return "unknown"; + } +} + +// Checked: 2012-07-29 (RLVa-1.4.7) +std::string rlvFolderLockPermissionToString(RlvFolderLocks::ELockPermission eLockPermission) +{ + switch (eLockPermission) + { + case RlvFolderLocks::PERM_ALLOW: + return "allow"; + case RlvFolderLocks::PERM_DENY: + return "deny"; + default: + return "unknown"; + } +} + +// Checked: 2012-07-29 (RLVa-1.4.7) +std::string rlvFolderLockScopeToString(RlvFolderLocks::ELockScope eLockScope) +{ + switch (eLockScope) + { + case RlvFolderLocks::SCOPE_NODE: + return "node"; + case RlvFolderLocks::SCOPE_SUBTREE: + return "subtree"; + default: + return "unknown"; + } +} + +// Checked: 2012-07-29 (RLVa-1.4.7) +std::string rlvFolderLockSourceToTarget(RlvFolderLocks::folderlock_source_t lockSource) +{ + switch (lockSource.first) + { + case RlvFolderLocks::ST_ATTACHMENT: + { + std::string strAttachName = rlvGetItemNameFromObjID(boost::get(lockSource.second)); + return llformat("Attachment (%s)", strAttachName.c_str()); + } + case RlvFolderLocks::ST_ATTACHMENTPOINT: + { + const LLViewerJointAttachment* pAttachPt = RlvAttachPtLookup::getAttachPoint(boost::get(lockSource.second)); + return llformat("Attachment point (%s)", (pAttachPt) ? pAttachPt->getName().c_str() : "Unknown"); + } + case RlvFolderLocks::ST_FOLDER: + { + return "Folder: "; + } + case RlvFolderLocks::ST_ROOTFOLDER: + { + return "Root folder"; + } + case RlvFolderLocks::ST_SHAREDPATH: + { + const std::string& strPath = boost::get(lockSource.second); + return llformat("Shared path (#RLV%s%s)", (!strPath.empty()) ? "/" : "", strPath.c_str()); + } + case RlvFolderLocks::ST_WEARABLETYPE: + { + const std::string& strTypeName = LLWearableType::getTypeName(boost::get(lockSource.second)); + return llformat("Wearable type (%s)", strTypeName.c_str()); + } + default: + { + return "(Unknown)"; + } + } +} + // ============================================================================ // RlvFloaterBehaviours member functions // @@ -381,6 +500,187 @@ void RlvFloaterLocks::refreshAll() pLockList->addElement(sdRow, ADD_BOTTOM); } + + // + // List "nostrip" (soft) locks + // + sdColumns[1]["value"] = "nostrip"; + sdColumns[3]["value"] = "(Agent)"; + + LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; + LLFindWearablesEx f(true, true); + gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), folders, items, FALSE, f); + + for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem) + { + const LLViewerInventoryItem* pItem = *itItem; + if (!RlvForceWear::instance().isStrippable(pItem->getUUID())) + { + sdColumns[0]["value"] = rlvGetItemType(pItem); + sdColumns[2]["value"] = rlvGetItemName(pItem); + + pLockList->addElement(sdRow, ADD_BOTTOM); + } + } + + // + // List folder locks + // + { + // Folder lock descriptors + const RlvFolderLocks::folderlock_list_t& folderLocks = RlvFolderLocks::instance().getFolderLocks(); + for (RlvFolderLocks::folderlock_list_t::const_iterator itFolderLock = folderLocks.begin(); + itFolderLock != folderLocks.end(); ++itFolderLock) + { + const RlvFolderLocks::folderlock_descr_t* pLockDescr = *itFolderLock; + if (pLockDescr) + { + sdColumns[0]["value"] = "Folder Descriptor"; + sdColumns[1]["value"] = + rlvLockMaskToString(pLockDescr->eLockType) + "/" + + rlvFolderLockPermissionToString(pLockDescr->eLockPermission) + "/" + + rlvFolderLockScopeToString(pLockDescr->eLockScope); + sdColumns[2]["value"] = rlvFolderLockSourceToTarget(pLockDescr->lockSource); + sdColumns[3]["value"] = rlvGetItemNameFromObjID(pLockDescr->idRlvObj); + + pLockList->addElement(sdRow, ADD_BOTTOM); + } + } + } + + { + // Folder locked attachments and wearables + uuid_vec_t idItems; + const uuid_vec_t& folderLockAttachmentsIds = RlvFolderLocks::instance().getAttachmentLookups(); + idItems.insert(idItems.end(), folderLockAttachmentsIds.begin(), folderLockAttachmentsIds.end()); + const uuid_vec_t& folderLockWearabels = RlvFolderLocks::instance().getWearableLookups(); + idItems.insert(idItems.end(), folderLockWearabels.begin(), folderLockWearabels.end()); + + for (uuid_vec_t::const_iterator itItemId = idItems.begin(); itItemId != idItems.end(); ++itItemId) + { + const LLViewerInventoryItem* pItem = gInventory.getItem(*itItemId); + if (pItem) + { + sdColumns[0]["value"] = rlvGetItemType(pItem); + sdColumns[1]["value"] = rlvLockMaskToString(RLV_LOCK_REMOVE); + sdColumns[2]["value"] = rlvGetItemName(pItem); + sdColumns[3]["value"] = ""; + + pLockList->addElement(sdRow, ADD_BOTTOM); + } + } + } +} + +// ============================================================================ +// RlvFloaterStrings member functions +// + +// Checked: 2011-11-08 (RLVa-1.5.0) +RlvFloaterStrings::RlvFloaterStrings(const LLSD& sdKey) + : LLFloater(sdKey) + , m_fDirty(false) + , m_pStringList(NULL) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_rlv_strings.xml"); +} + +// Checked: 2011-11-08 (RLVa-1.5.0) +BOOL RlvFloaterStrings::postBuild() +{ + // Set up the UI controls + m_pStringList = findChild("string_list"); + m_pStringList->setCommitCallback(boost::bind(&RlvFloaterStrings::checkDirty, this, true)); + + LLUICtrl* pDefaultBtn = findChild("default_btn"); + pDefaultBtn->setCommitCallback(boost::bind(&RlvFloaterStrings::onStringRevertDefault, this)); + + // Read all string metadata from the default strings file + llifstream fileStream(RlvStrings::getStringMapPath(), std::ios::binary); LLSD sdFileData; + if ( (fileStream.is_open()) && (LLSDSerialize::fromXMLDocument(sdFileData, fileStream)) ) + { + m_sdStringsInfo = sdFileData["strings"]; + fileStream.close(); + } + + // Populate the combo box + for (LLSD::map_const_iterator itString = m_sdStringsInfo.beginMap(); itString != m_sdStringsInfo.endMap(); ++itString) + { + const LLSD& sdStringInfo = itString->second; + if ( (!sdStringInfo.has("customizable")) || (!sdStringInfo["customizable"].asBoolean()) ) + continue; + m_pStringList->add( (sdStringInfo.has("label")) ? sdStringInfo["label"].asString() : itString->first, itString->first); + } + + refresh(); + + return TRUE; +} + +// Checked: 2011-11-08 (RLVa-1.5.0) +void RlvFloaterStrings::onClose(bool fQuitting) +{ + checkDirty(false); + if (m_fDirty) + { + // Save the custom string overrides + RlvStrings::saveToFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, RLV_STRINGS_FILE)); + + if (!fQuitting) // Singu Note: We're done if fQuitting, don't notify + // Remind the user their changes require a relog to take effect + LLNotificationsUtil::add("RLVChangeStrings"); + } + + if (fQuitting) destroy(); + else setVisible(false); // Hide when closing. +} + +// Checked: 2011-11-08 (RLVa-1.5.0) +void RlvFloaterStrings::onStringRevertDefault() +{ + if (!m_strStringCurrent.empty()) + { + RlvStrings::setCustomString(m_strStringCurrent, LLStringUtil::null); + m_fDirty = true; + } + refresh(); +} + +// Checked: 2011-11-08 (RLVa-1.5.0) +void RlvFloaterStrings::checkDirty(bool fRefresh) +{ + LLTextEditor* pStringValue = findChild("string_value"); + if (!pStringValue->isPristine()) + { + RlvStrings::setCustomString(m_strStringCurrent, pStringValue->getText()); + m_fDirty = true; + } + + if (fRefresh) + { + refresh(); + } +} + +// Checked: 2011-11-08 (RLVa-1.5.0) +void RlvFloaterStrings::refresh() +{ + m_strStringCurrent = (-1 != m_pStringList->getCurrentIndex()) ? m_pStringList->getSelectedValue().asString() : LLStringUtil::null; + + LLTextEditor* pStringDescr = findChild("string_descr"); + pStringDescr->clear(); + LLTextEditor* pStringValue = findChild("string_value"); + pStringValue->setEnabled(!m_strStringCurrent.empty()); + pStringValue->clear(); + if (!m_strStringCurrent.empty()) + { + if (m_sdStringsInfo[m_strStringCurrent].has("description")) + pStringDescr->setText(m_sdStringsInfo[m_strStringCurrent]["description"].asString()); + pStringValue->setText(RlvStrings::getString(m_strStringCurrent)); + pStringValue->makePristine(); + } + + findChild("default_btn")->setEnabled(!m_strStringCurrent.empty()); } // ============================================================================ diff --git a/indra/newview/rlvfloaters.h b/indra/newview/rlvfloaters.h index 33b8ed9fa..daeac993b 100644 --- a/indra/newview/rlvfloaters.h +++ b/indra/newview/rlvfloaters.h @@ -22,11 +22,19 @@ #include "rlvdefines.h" #include "rlvcommon.h" +template +struct VisibleToggle +{ + static void toggle(void*) { return T::toggleInstance(); } + static BOOL visible(void*) { return T::instanceVisible(); } +}; + // ============================================================================ // RlvFloaterLocks class declaration // -class RlvFloaterBehaviours : public LLFloater, public LLFloaterSingleton +class RlvFloaterBehaviours : public LLFloater +, public LLFloaterSingleton, public VisibleToggle { friend class LLUISingleton >; private: @@ -40,9 +48,6 @@ public: /*virtual*/ void onClose(bool fQuitting); /*virtual*/ BOOL postBuild(); - static void toggle(void*) { return toggleInstance(); } - static BOOL visible(void*) { return instanceVisible(); } - /* * Member functions */ @@ -64,7 +69,8 @@ protected: // RlvFloaterLocks class declaration // -class RlvFloaterLocks : public LLFloater, public LLFloaterSingleton +class RlvFloaterLocks : public LLFloater +, public LLFloaterSingleton, public VisibleToggle { friend class LLUISingleton >; private: @@ -78,9 +84,6 @@ public: /*virtual*/ void onClose(bool fQuitting); /*virtual*/ BOOL postBuild(); - static void toggle(void*) { return toggleInstance(); } - static BOOL visible(void*) { return instanceVisible(); } - /* * Member functions */ @@ -96,5 +99,35 @@ protected: }; // ============================================================================ +// RlvFloaterStrings class declaration +// -#endif // RLV_FLOATERS_H \ No newline at end of file +class RlvFloaterStrings : public LLFloater +, public LLFloaterSingleton, public VisibleToggle +{ + friend class LLUISingleton >; +private: + RlvFloaterStrings(const LLSD& sdKey); + + // LLFloater overrides +public: + /*virtual*/ void onClose(bool fQuitting); + /*virtual*/ BOOL postBuild(); + + // Member functions +protected: + void onStringRevertDefault(); + void checkDirty(bool fRefresh); + void refresh(); + + // Member variables +protected: + bool m_fDirty; + std::string m_strStringCurrent; + LLComboBox* m_pStringList; + LLSD m_sdStringsInfo; +}; + +// ============================================================================ + +#endif // RLV_FLOATERS_H diff --git a/indra/newview/skins/default/xui/en-us/floater_rlv_strings.xml b/indra/newview/skins/default/xui/en-us/floater_rlv_strings.xml new file mode 100644 index 000000000..f3ea7a010 --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/floater_rlv_strings.xml @@ -0,0 +1,52 @@ + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index 307424ff0..eaf0d0fb7 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -9693,6 +9693,14 @@ Cannot create large prims that intersect other players. Please re-try when othe + + +Changes won't take effect until after you restart [APP_NAME]. + +