summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llassettype.cpp17
-rw-r--r--indra/llcommon/llassettype.h2
-rw-r--r--indra/llinventory/llfoldertype.cpp1
-rw-r--r--indra/newview/llinventorylistener.cpp140
-rw-r--r--indra/newview/llinventorylistener.h27
-rw-r--r--indra/newview/scripts/lua/require/LLInventory.lua19
6 files changed, 200 insertions, 6 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 3e46bde954..1c0893b1bf 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -30,6 +30,7 @@
#include "lldictionary.h"
#include "llmemory.h"
#include "llsingleton.h"
+#include "llsd.h"
///----------------------------------------------------------------------------
/// Class LLAssetType
@@ -244,3 +245,19 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type)
}
return false;
}
+
+LLSD LLAssetType::getTypeNames()
+{
+ LLSD type_names;
+ const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
+ for (S32 type = AT_TEXTURE; type < AT_COUNT; ++type)
+ {
+ const AssetEntry *entry = dict->lookup((LLAssetType::EType) type);
+ // skip llassettype_bad_lookup
+ if (entry)
+ {
+ type_names.append(entry->mTypeName);
+ }
+ }
+ return type_names;
+}
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 1989155550..4185063ae5 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -163,6 +163,8 @@ public:
static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
+ static LLSD getTypeNames();
+
static const std::string BADLOOKUP;
protected:
diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp
index 158759c957..c8ef1ccc1b 100644
--- a/indra/llinventory/llfoldertype.cpp
+++ b/indra/llinventory/llfoldertype.cpp
@@ -230,6 +230,7 @@ LLSD LLFolderType::getTypeNames()
if (lookupIsEnsembleType((LLFolderType::EType)type)) continue;
const FolderEntry *entry = LLFolderDictionary::getInstance()->lookup((LLFolderType::EType)type);
+ //skip llfoldertype_bad_lookup
if (entry)
{
type_names.append(entry->mName);
diff --git a/indra/newview/llinventorylistener.cpp b/indra/newview/llinventorylistener.cpp
index a8269bb80d..4beb59c58e 100644
--- a/indra/newview/llinventorylistener.cpp
+++ b/indra/newview/llinventorylistener.cpp
@@ -48,6 +48,11 @@ LLInventoryListener::LLInventoryListener()
&LLInventoryListener::getFolderTypeNames,
llsd::map("reply", LLSD()));
+ add("getAssetTypeNames",
+ "Return the table of asset type names, contained in [\"type_names\"]\n",
+ &LLInventoryListener::getAssetTypeNames,
+ llsd::map("reply", LLSD()));
+
add("getBasicFolderID",
"Return the UUID of the folder by specified folder type name, for example:\n"
"\"Textures\", \"My outfits\", \"Sounds\" and other basic folders which have associated type",
@@ -58,6 +63,15 @@ LLInventoryListener::LLInventoryListener()
"Return the direct descendents(both items and folders) of the [\"folder_id\"]",
&LLInventoryListener::getDirectDescendents,
llsd::map("folder_id", LLSD(), "reply", LLSD()));
+
+ add("collectDescendentsIf",
+ "Return the descendents(both items and folders) of the [\"folder_id\"], if it passes specified filters:\n"
+ "[\"name\"] is a substring of object's name,\n"
+ "[\"desc\"] is a substring of object's description,\n"
+ "asset [\"type\"] corresponds to the object's asset type\n"
+ "[\"filter_links\"]: EXCLUDE_LINKS - don't show links, ONLY_LINKS - only show links, INCLUDE_LINKS - show links too (default)",
+ &LLInventoryListener::collectDescendentsIf,
+ llsd::map("folder_id", LLSD(), "reply", LLSD()));
}
@@ -65,17 +79,15 @@ void add_item_info(LLEventAPI::Response& response, LLViewerInventoryItem* item)
{
response["items"].insert(item->getUUID().asString(),
llsd::map("name", item->getName(), "parent_id", item->getParentUUID(), "desc", item->getDescription(),
- "inv_type", LLInventoryType::lookup(item->getInventoryType()), "creation_date",
- (S32) item->getCreationDate(), "asset_id", item->getAssetUUID(), "is_link", item->getIsLinkType(),
- "linked_id", item->getLinkedUUID()));
+ "inv_type", LLInventoryType::lookup(item->getInventoryType()), "asset_type", LLAssetType::lookup(item->getType()),
+ "creation_date", (S32) item->getCreationDate(), "asset_id", item->getAssetUUID(),
+ "is_link", item->getIsLinkType(), "linked_id", item->getLinkedUUID()));
}
void add_cat_info(LLEventAPI::Response &response, LLViewerInventoryCategory *cat)
{
response["categories"].insert(cat->getUUID().asString(),
- llsd::map("name", cat->getName(), "parent_id", cat->getParentUUID(), "type",
- LLFolderType::lookup(cat->getPreferredType()), "creation_date", (S32) cat->getCreationDate(),
- "is_link", cat->getIsLinkType(), "linked_id", cat->getLinkedUUID()));
+ llsd::map("name", cat->getName(), "parent_id", cat->getParentUUID(), "type", LLFolderType::lookup(cat->getPreferredType())));
}
void LLInventoryListener::getItemsInfo(LLSD const &data)
@@ -103,6 +115,11 @@ void LLInventoryListener::getFolderTypeNames(LLSD const &data)
Response response(llsd::map("type_names", LLFolderType::getTypeNames()), data);
}
+void LLInventoryListener::getAssetTypeNames(LLSD const &data)
+{
+ Response response(llsd::map("type_names", LLAssetType::getTypeNames()), data);
+}
+
void LLInventoryListener::getBasicFolderID(LLSD const &data)
{
Response response(llsd::map("id", gInventory.findCategoryUUIDForType(LLFolderType::lookup(data["ft_name"].asString()))), data);
@@ -128,3 +145,114 @@ void LLInventoryListener::getDirectDescendents(LLSD const &data)
}
}
+void LLInventoryListener::collectDescendentsIf(LLSD const &data)
+{
+ Response response(LLSD(), data);
+ LLUUID folder_id(data["folder_id"].asUUID());
+ LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
+ if (!cat)
+ {
+ return response.error(stringize("Folder ", std::quoted(data["folder_id"].asString()), " was not found"));
+ }
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+
+ LLFilteredCollector collector = LLFilteredCollector(data);
+
+ gInventory.collectDescendentsIf(folder_id, cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, collector);
+
+ for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); iter != item_array.end(); iter++)
+ {
+ add_item_info(response, *iter);
+ }
+ for (LLInventoryModel::cat_array_t::iterator iter = cat_array.begin(); iter != cat_array.end(); iter++)
+ {
+ add_cat_info(response, *iter);
+ }
+}
+
+LLFilteredCollector::LLFilteredCollector(LLSD const &data)
+ : mType(LLAssetType::EType::AT_UNKNOWN),
+ mLinkFilter(INCLUDE_LINKS)
+{
+ if (data.has("name"))
+ {
+ mName = data["name"];
+ }
+ if (data.has("desc"))
+ {
+ mDesc = data["desc"];
+ }
+ if (data.has("type"))
+ {
+ mType = LLAssetType::lookup(data["type"]);
+ }
+ if (data.has("filter_links"))
+ {
+ if (data["filter_links"] == "EXCLUDE_LINKS")
+ {
+ mLinkFilter = EXCLUDE_LINKS;
+ }
+ else if (data["filter_links"] == "ONLY_LINKS")
+ {
+ mLinkFilter = ONLY_LINKS;
+ }
+ }
+}
+
+bool LLFilteredCollector::operator()(LLInventoryCategory *cat, LLInventoryItem *item)
+{
+ bool passed = checkagainstType(cat, item);
+ passed = passed && checkagainstNameDesc(cat, item);
+ passed = passed && checkagainstLinks(cat, item);
+
+ return passed;
+}
+
+bool LLFilteredCollector::checkagainstNameDesc(LLInventoryCategory *cat, LLInventoryItem *item)
+{
+ std::string name, desc;
+ bool passed(true);
+ if (cat)
+ {
+ if (!mDesc.empty()) return false;
+ name = cat->getName();
+ }
+ if (item)
+ {
+ name = item->getName();
+ passed = (mDesc.size() ? item->getDescription().find(mDesc) != std::string::npos : true);
+ }
+
+ return passed && (mName.size() ? name.find(mName) != std::string::npos : true);
+}
+
+bool LLFilteredCollector::checkagainstType(LLInventoryCategory *cat, LLInventoryItem *item)
+{
+ if (mType == LLAssetType::AT_UNKNOWN)
+ {
+ return true;
+ }
+ if (mType == LLAssetType::AT_CATEGORY)
+ {
+ if (cat)
+ {
+ return true;
+ }
+ }
+ if (item && item->getType() == mType)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool LLFilteredCollector::checkagainstLinks(LLInventoryCategory *cat, LLInventoryItem *item)
+{
+ bool is_link = cat ? cat->getIsLinkType() : item->getIsLinkType();
+ if (is_link && (mLinkFilter == EXCLUDE_LINKS))
+ return false;
+ if (!is_link && (mLinkFilter == ONLY_LINKS))
+ return false;
+ return true;
+}
diff --git a/indra/newview/llinventorylistener.h b/indra/newview/llinventorylistener.h
index e148df48fe..83e1751e1b 100644
--- a/indra/newview/llinventorylistener.h
+++ b/indra/newview/llinventorylistener.h
@@ -28,6 +28,7 @@
#define LL_LLINVENTORYLISTENER_H
#include "lleventapi.h"
+#include "llinventoryfunctions.h"
class LLInventoryListener : public LLEventAPI
{
@@ -37,8 +38,34 @@ public:
private:
void getItemsInfo(LLSD const &data);
void getFolderTypeNames(LLSD const &data);
+ void getAssetTypeNames(LLSD const &data);
void getBasicFolderID(LLSD const &data);
void getDirectDescendents(LLSD const &data);
+ void collectDescendentsIf(LLSD const &data);
+};
+
+struct LLFilteredCollector : public LLInventoryCollectFunctor
+{
+ enum EFilterLink
+ {
+ INCLUDE_LINKS, // show links too
+ EXCLUDE_LINKS, // don't show links
+ ONLY_LINKS // only show links
+ };
+
+ LLFilteredCollector(LLSD const &data);
+ virtual ~LLFilteredCollector() {}
+ virtual bool operator()(LLInventoryCategory *cat, LLInventoryItem *item);
+
+ protected:
+ bool checkagainstType(LLInventoryCategory *cat, LLInventoryItem *item);
+ bool checkagainstNameDesc(LLInventoryCategory *cat, LLInventoryItem *item);
+ bool checkagainstLinks(LLInventoryCategory *cat, LLInventoryItem *item);
+
+ LLAssetType::EType mType;
+ std::string mName;
+ std::string mDesc;
+ EFilterLink mLinkFilter;
};
#endif // LL_LLINVENTORYLISTENER_H
diff --git a/indra/newview/scripts/lua/require/LLInventory.lua b/indra/newview/scripts/lua/require/LLInventory.lua
index 880a2516f1..e6a347532b 100644
--- a/indra/newview/scripts/lua/require/LLInventory.lua
+++ b/indra/newview/scripts/lua/require/LLInventory.lua
@@ -19,10 +19,29 @@ function LLInventory.getBasicFolderID(ft_name)
return leap.request('LLInventory', {op = 'getBasicFolderID', ft_name=ft_name}).id
end
+-- Get the table of asset type names, which can be later used to get the specific items via LLInventory.collectDescendentsIf(...)
+function LLInventory.getAssetTypeNames()
+ return leap.request('LLInventory', {op = 'getAssetTypeNames'}).type_names
+end
+
-- Get the direct descendents of the 'folder_id' provided,
-- reply will contain "items" and "categories" tables accordingly
function LLInventory.getDirectDescendents(folder_id)
return leap.request('LLInventory', {op = 'getDirectDescendents', folder_id=folder_id})
end
+-- Get the descendents of the 'folder_id' provided, which pass specified filters
+-- reply will contain "items" and "categories" tables accordingly
+-- LLInventory.collectDescendentsIf{ folder_id -- parent folder ID
+-- [, name] -- name (substring)
+-- [, desc] -- description (substring)
+-- [, type] -- asset type
+-- [, filter_links]} -- EXCLUDE_LINKS - don't show links, ONLY_LINKS - only show links, INCLUDE_LINKS - show links too (default)
+function LLInventory.collectDescendentsIf(...)
+ local args = mapargs('folder_id,name,desc,type,filter_links', ...)
+ args.op = 'collectDescendentsIf'
+ return leap.request('LLInventory', args)
+end
+
+
return LLInventory