summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llinventorybridge.cpp97
-rw-r--r--indra/newview/llinventorybridge.h11
-rw-r--r--indra/newview/llinventorypanel.cpp15
-rw-r--r--indra/newview/llviewerinventory.cpp49
-rw-r--r--indra/newview/llviewerinventory.h22
5 files changed, 134 insertions, 60 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index c8ea14a11e..8e4e70474f 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -249,11 +249,27 @@ const std::string& LLInvFVBridge::getName() const
const std::string& LLInvFVBridge::getDisplayName() const
{
- if(mDisplayName.empty())
+ if(mSearchableName.empty())
{
- buildDisplayName();
+ // first request of display name, build search string and cache it for later use
+ buildSearchableName();
}
- return mDisplayName;
+
+ LLInventoryModel* model = getInventoryModel();
+ if (model)
+ {
+ LLViewerInventoryCategory* cat = model->getCategory(mUUID);
+ if (cat)
+ {
+ return cat->getDisplayName();
+ }
+ LLViewerInventoryItem* item = model->getItem(mUUID);
+ if (item)
+ {
+ return item->getName();
+ }
+ }
+ return LLStringUtil::null;
}
std::string LLInvFVBridge::getSearchableDescription() const
@@ -2035,22 +2051,22 @@ PermissionMask LLItemBridge::getPermissionMask() const
}
// virtual
-void LLItemBridge::buildDisplayName() const
+void LLItemBridge::buildSearchableName() const
{
- if (getItem())
+ LLViewerInventoryItem* item = getItem();
+ if (item)
{
- mDisplayName.assign(getItem()->getName());
+ // for items, display name matches item name
+ mSearchableName.assign(item->getName());
}
else
{
- mDisplayName.assign(LLStringUtil::null);
+ mSearchableName.assign(LLStringUtil::null);
}
-
- mSearchableName.assign(mDisplayName);
mSearchableName.append(getLabelSuffix());
LLStringUtil::toUpper(mSearchableName);
- // Name set, so trigger a sort
+ // Searchable and name set, so trigger a sort
LLInventorySort sorter = static_cast<LLFolderViewModelInventory&>(mRootViewModel).getSorter();
if (mParent && !sorter.isByDate())
{
@@ -2371,39 +2387,17 @@ void LLFolderBridge::selectItem()
}
}
-void LLFolderBridge::buildDisplayName() const
+void LLFolderBridge::buildSearchableName() const
{
- LLFolderType::EType preferred_type = getPreferredType();
-
- // *TODO: to be removed when database supports multi language. This is a
- // temporary attempt to display the inventory folder in the user locale.
- // mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
- // it uses the same way to find localized string
-
- // HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
- // Translation of Accessories folder in Library inventory folder
- bool accessories = false;
- if(getName() == "Accessories")
+ LLViewerInventoryCategory* cat = gInventory.getCategory(getUUID());
+ if (cat)
{
- //To ensure that Accessories folder is in Library we have to check its parent folder.
- //Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
- LLInventoryCategory* cat = gInventory.getCategory(getUUID());
- if(cat)
- {
- const LLUUID& parent_folder_id = cat->getParentUUID();
- accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
- }
+ mSearchableName.assign(cat->getDisplayName());
}
-
- //"Accessories" inventory category has folder type FT_NONE. So, this folder
- //can not be detected as protected with LLFolderType::lookupIsProtectedType
- mDisplayName.assign(getName());
- if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
+ else
{
- LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
+ mSearchableName.assign(LLStringUtil::null);
}
-
- mSearchableName.assign(mDisplayName);
mSearchableName.append(getLabelSuffix());
LLStringUtil::toUpper(mSearchableName);
@@ -2417,6 +2411,8 @@ void LLFolderBridge::buildDisplayName() const
std::string LLFolderBridge::getLabelSuffix() const
{
+ // Folders, unlike items, have context dependent suffixes
+ // that may change as the folder is loaded
static LLCachedControl<bool> xui_debug(gSavedSettings, "DebugShowXUINames", 0);
if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= FOLDER_LOADING_MESSAGE_DELAY)
@@ -6576,18 +6572,29 @@ void LLCallingCardBridge::refreshFolderViewItem()
void LLCallingCardBridge::checkSearchBySuffixChanges()
{
- if (!mDisplayName.empty())
+ if (!mSearchableName.empty())
{
- // changes in mDisplayName are processed by rename function and here it will be always same
+ LLViewerInventoryItem* item = getItem();
+ if (!item)
+ {
+ // checkSearchBySuffixChanges is only used by friend list
+ // so if item is not found, we removed the calling card or
+ // are no longer friends.
+ mSearchableName.clear();
+ return;
+ }
+
+ // changes in display name are processed by rename function and here it will be always same
// suffixes are also of fixed length, and we are processing change of one at a time,
// so it should be safe to use length (note: mSearchableName is capitalized)
- auto old_length = mSearchableName.length();
- auto new_length = mDisplayName.length() + getLabelSuffix().length();
+ size_t old_length = mSearchableName.length();
+ const std::string& display_name = item->getName();
+ size_t new_length = display_name.length() + getLabelSuffix().length();
if (old_length == new_length)
{
return;
}
- mSearchableName.assign(mDisplayName);
+ mSearchableName.assign(display_name);
mSearchableName.append(getLabelSuffix());
LLStringUtil::toUpper(mSearchableName);
if (new_length<old_length)
@@ -7465,7 +7472,7 @@ bool LLObjectBridge::renameItem(const std::string& new_name)
new_item->updateServer(false);
model->updateItem(new_item);
model->notifyObservers();
- buildDisplayName();
+ buildSearchableName();
if (isAgentAvatarValid())
{
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index decb2c0528..68e7a7f80e 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -87,7 +87,7 @@ public:
virtual const LLUUID& getUUID() const { return mUUID; }
virtual const LLUUID& getThumbnailUUID() const { return LLUUID::null; }
virtual bool isFavorite() const { return false; }
- virtual void clearDisplayName() { mDisplayName.clear(); }
+ virtual void clearSearchableName() { mSearchableName.clear(); }
virtual void restoreItem() {}
virtual void restoreToWorld() {}
@@ -202,12 +202,11 @@ protected:
LLInventoryType::EType mInvType;
bool mIsLink;
LLTimer mTimeSinceRequestStart;
- mutable std::string mDisplayName;
mutable std::string mSearchableName;
void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
void removeObject(LLInventoryModel *model, const LLUUID &uuid);
- virtual void buildDisplayName() const {}
+ virtual void buildSearchableName() const {}
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -266,7 +265,7 @@ public:
protected:
bool confirmRemoveItem(const LLSD& notification, const LLSD& response);
virtual bool isItemPermissive() const;
- virtual void buildDisplayName() const;
+ virtual void buildSearchableName() const;
void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
private:
@@ -287,7 +286,7 @@ public:
void callback_dropItemIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item);
void callback_dropCategoryIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryCategory* inv_category);
- virtual void buildDisplayName() const;
+ virtual void buildSearchableName() const;
virtual void performAction(LLInventoryModel* model, std::string action);
virtual void openItem();
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 06dd830416..e87ef025c6 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -581,8 +581,9 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getViewModelItem();
if(bridge)
{
- // Clear the display name first, so it gets properly re-built during refresh()
- bridge->clearDisplayName();
+ // Clear the searchable name first, so it gets
+ // properly re-built during refresh()
+ bridge->clearSearchableName();
view_item->refresh();
}
@@ -1676,7 +1677,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
LLFolderBridge* prev_bridge = (LLFolderBridge*)prev_folder_item->getViewModelItem();
if(prev_bridge)
{
- prev_bridge->clearDisplayName();
+ prev_bridge->clearSearchableName();
prev_bridge->setShowDescendantsCount(false);
prev_folder_item->refresh();
}
@@ -1685,7 +1686,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem();
if(bridge)
{
- bridge->clearDisplayName();
+ bridge->clearSearchableName();
bridge->setShowDescendantsCount(true);
folder_item->refresh();
mPreviousSelectedFolder = bridge->getUUID();
@@ -1700,7 +1701,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
LLFolderBridge* prev_bridge = (LLFolderBridge*)prev_folder_item->getViewModelItem();
if(prev_bridge)
{
- prev_bridge->clearDisplayName();
+ prev_bridge->clearSearchableName();
prev_bridge->setShowDescendantsCount(false);
prev_folder_item->refresh();
}
@@ -1720,7 +1721,7 @@ void LLInventoryPanel::updateFolderLabel(const LLUUID& folder_id)
LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem();
if(bridge)
{
- bridge->clearDisplayName();
+ bridge->clearSearchableName();
bridge->setShowDescendantsCount(true);
folder_item->refresh();
}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index efa3f5cd1e..707b2f1993 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2014, Linden Research, Inc.
+ * Copyright (C) 2026, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -673,6 +673,25 @@ void LLViewerInventoryCategory::setVersion(S32 version)
mVersion = version;
}
+const std::string& LLViewerInventoryCategory::getDisplayName() const
+{
+ if (mNeedsDisplayNameUpdate)
+ {
+ buildDisplayName();
+ }
+ if (!mDisplayName.empty())
+ {
+ return mDisplayName;
+ }
+ return getName();
+}
+
+void LLViewerInventoryCategory::invalidateDisplayName()
+{
+ mNeedsDisplayNameUpdate = true;
+ mDisplayName.clear();
+}
+
bool LLViewerInventoryCategory::fetch(S32 expiry_seconds)
{
if((VERSION_UNKNOWN == getVersion())
@@ -889,6 +908,34 @@ void LLViewerInventoryCategory::localizeName()
LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName);
}
+void LLViewerInventoryCategory::buildDisplayName() const
+{
+ // Secure and library folders can't be renamed,
+ // so we only need to do this once.
+ mNeedsDisplayNameUpdate = false;
+
+ //"Accessories" inventory category has folder type FT_NONE. So, this folder
+ //can not be detected as protected with LLFolderType::lookupIsProtectedType
+ //
+ // HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
+ // Translation of Accessories folder in Library inventory folder
+ LLFolderType::EType preferred_type = getPreferredType();
+
+ bool is_accessories = false;
+ if (getName() == "Accessories")
+ {
+ // To ensure that Accessories folder is in Library we have to check its parent folder.
+ const LLUUID& parent_folder_id = getParentUUID();
+ is_accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
+ }
+
+ if (is_accessories || LLFolderType::lookupIsProtectedType(preferred_type))
+ {
+ // All predefined folders have translations in strings.xml.
+ LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
+ }
+}
+
// virtual
bool LLViewerInventoryCategory::unpackMessage(const LLSD& category)
{
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index a42bdaa2b0..f14850da5a 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2026, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -209,6 +209,13 @@ public:
S32 getVersion() const;
void setVersion(S32 version);
+ const std::string& getDisplayName() const;
+ // The display name gets cached on demand, so needs a cleanup method.
+ // But in practice only secure folders' display name mismatches
+ // actual name, and those folders can't be renamed, so in practice
+ // this is useless unless we want to free memory.
+ void invalidateDisplayName();
+
// Returns true if a fetch was issued (not nessesary in progress).
// no requests will happen during expiry_seconds even if fetch completed
bool fetch(S32 expiry_seconds = 10);
@@ -253,6 +260,19 @@ protected:
S32 mDescendentCount;
EFetchType mFetching;
LLFrameTimer mDescendentsRequested;
+
+ // Display names are generated on demand and cached.
+ // buildDisplayName is essentially a way to localize
+ // system and library folders.
+ //
+ // TODO: This is on demand and mutable because that's how it
+ // worked in inventory bridge, before it was moved.
+ // But system folders always get loaded, it's likely better
+ // to just generate from the get go.
+ // Consider merging with localizeName.
+ void buildDisplayName() const;
+ mutable std::string mDisplayName;
+ mutable bool mNeedsDisplayNameUpdate = true;
};
class LLInventoryCallback : public LLRefCount