void LLFloaterOutbox::updateFolderCount() { if (mOutboxInventoryPanel.get() && mOutboxId.notNull()) { S32 item_count = 0; if (mOutboxId.notNull()) { LLInventoryModel::cat_array_t * cats; LLInventoryModel::item_array_t * items; gInventory.getDirectDescendentsOf(mOutboxId, cats, items); item_count = cats->count() + items->count(); } mOutboxItemCount = item_count; } else { // If there's no outbox, the number of items in it should be set to 0 for consistency mOutboxItemCount = 0; } if (!mImportBusy) { updateFolderCountStatus(); } }
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.0.1a LLViewerInventoryCategory* RlvInventory::getSharedFolder(const LLUUID& idParent, const std::string& strFolderName) const { LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems; gInventory.getDirectDescendentsOf(idParent, pFolders, pItems); if ( (!pFolders) || (strFolderName.empty()) ) return NULL; // If we can't find an exact match then we'll settle for a "contains" match LLViewerInventoryCategory* pPartial = NULL; //LLStringUtil::toLower(strFolderName); <- everything was already converted to lower case before std::string strName; for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++) { LLViewerInventoryCategory* pFolder = pFolders->get(idxFolder); strName = pFolder->getName(); if (strName.empty()) continue; LLStringUtil::toLower(strName); if (strFolderName == strName) return pFolder; // Found an exact match, no need to keep on going else if ( (!pPartial) && (RLV_FOLDER_PREFIX_HIDDEN != strName[0]) && (std::string::npos != strName.find(strFolderName)) ) pPartial = pFolder; // Found a partial (non-hidden) match, but we might still find an exact one (first partial match wins) } return pPartial; }
// Checked: 2010-02-28 (RLVa-1.1.3a) | Modified: RLVa-1.0.0h void RlvInventory::fetchSharedInventory() { // Sanity check - don't fetch if we're already fetching, or if we don't have a shared root const LLViewerInventoryCategory* pRlvRoot = getSharedRoot(); if ( (m_fFetchStarted) || (!pRlvRoot) ) return; // Grab all the folders under the shared root LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; gInventory.collectDescendents(pRlvRoot->getUUID(), folders, items, FALSE); // Add them to the "to fetch" list uuid_vec_t fetchFolders; fetchFolders.push_back(pRlvRoot->getUUID()); for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) fetchFolders.push_back(folders.get(idxFolder)->getUUID()); // Now fetch them all in one go RlvSharedInventoryFetcher* pFetcher = new RlvSharedInventoryFetcher(fetchFolders); RLV_INFOS << "Starting fetch of " << fetchFolders.size() << " shared folders" << RLV_ENDL; pFetcher->startFetch(); m_fFetchStarted = true; if (pFetcher->isFinished()) pFetcher->done(); else gInventory.addObserver(pFetcher); }
void LLFriendCardsManager::findMatchedFriendCards(const LLUUID& avatarID, LLInventoryModel::item_array_t& items) const { LLInventoryModel::cat_array_t cats; LLUUID friendFolderUUID = findFriendFolderUUIDImpl(); LLViewerInventoryCategory* friendFolder = gInventory.getCategory(friendFolderUUID); if (NULL == friendFolder) return; LLParticularBuddyCollector matchFunctor(avatarID); LLInventoryModel::cat_array_t subFolders; subFolders.push_back(friendFolder); while (subFolders.count() > 0) { LLViewerInventoryCategory* cat = subFolders.get(0); subFolders.remove(0); gInventory.collectDescendentsIf(cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, matchFunctor); move_from_to_arrays(cats, subFolders); } }
// Checked: 2011-10-06 (RLVa-1.4.2a) | Modified: RLVa-1.4.2a const LLUUID& RlvInventory::getSharedRootID() const { if ( (m_idRlvRoot.isNull()) && (gInventory.isInventoryUsable()) ) { LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems; gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), pFolders, pItems); if (pFolders) { // NOTE: we might have multiple #RLV folders (pick the first one with sub-folders; otherwise the last one with no sub-folders) const LLViewerInventoryCategory* pFolder; for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++) { if ( ((pFolder = pFolders->get(idxFolder)) != NULL) && (cstrSharedRoot == pFolder->getName()) ) { m_idRlvRoot = pFolder->getUUID(); if (getDirectDescendentsFolderCount(pFolder) > 0) break; } } if ( (m_idRlvRoot.notNull()) && (!gInventory.containsObserver((RlvInventory*)this)) ) gInventory.addObserver((RlvInventory*)this); } } return m_idRlvRoot; }
void move_from_to_arrays(LLInventoryModel::cat_array_t& from, LLInventoryModel::cat_array_t& to) { while (from.count() > 0) { to.put(from.get(0)); from.remove(0); } }
LLUUID FSLSLBridge::findFSBridgeContainerCategory() { llinfos << "Retrieving FSBridge container category (" << FS_BRIDGE_CONTAINER_FOLDER << ")" << llendl; if (mBridgeContainerFolderID.notNull()) { llinfos << "Returning FSBridge container category UUID from instance: " << mBridgeContainerFolderID << llendl; return mBridgeContainerFolderID; } LLUUID LibRootID = gInventory.getLibraryRootFolderID(); if (LibRootID.notNull()) { LLInventoryModel::item_array_t* items; LLInventoryModel::cat_array_t* cats; gInventory.getDirectDescendentsOf(LibRootID, cats, items); if (cats) { S32 count = cats->count(); for (S32 i = 0; i < count; ++i) { if (cats->get(i)->getName() == "Objects") { LLUUID LibObjectsCatID = cats->get(i)->getUUID(); if (LibObjectsCatID.notNull()) { LLInventoryModel::item_array_t* objects_items; LLInventoryModel::cat_array_t* objects_cats; gInventory.getDirectDescendentsOf(LibObjectsCatID, objects_cats, objects_items); if (objects_cats) { S32 objects_count = objects_cats->count(); for (S32 j = 0; j < objects_count; ++j) { if (objects_cats->get(j)->getName() == FS_BRIDGE_CONTAINER_FOLDER) { mBridgeContainerFolderID = objects_cats->get(j)->getUUID(); llinfos << "FSBridge container category found in library. UUID: " << mBridgeContainerFolderID << llendl; gInventory.fetchDescendentsOf(mBridgeContainerFolderID); return mBridgeContainerFolderID; } } } } } } } } llwarns << "FSBridge container category not found in library!" << llendl; return LLUUID(); }
// Checked: 2010-04-07 (RLVa-1.2.0a) | Modified: RLVa-1.0.0h bool RlvInventory::findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const { // Sanity check - can't do anything without a shared root const LLViewerInventoryCategory* pRlvRoot = RlvInventory::instance().getSharedRoot(); if (!pRlvRoot) return false; folders.clear(); LLInventoryModel::item_array_t items; RlvCriteriaCategoryCollector f(strCriteria); gInventory.collectDescendentsIf(pRlvRoot->getUUID(), folders, items, FALSE, f); return (folders.count() != 0); }
bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb) { S32 version = LLViewerInventoryCategory::VERSION_UNKNOWN; S32 current_num_known_descendents = LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN; bool can_be_added = true; LLViewerInventoryCategory* category = gInventory.getCategory(cat_id); // If category could not be retrieved it might mean that // inventory is unusable at the moment so the category is // stored with VERSION_UNKNOWN and DESCENDENT_COUNT_UNKNOWN, // it may be updated later. if (category) { // Inventory category version is used to find out if some changes // to a category have been made. version = category->getVersion(); LLInventoryModel::cat_array_t* cats; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(cat_id, cats, items); if (!cats || !items) { llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean // that the cat just doesn't have any items or subfolders). // Unrecoverable, so just return "false" meaning that the category can't be observed. can_be_added = false; llassert(cats != NULL && items != NULL); } else { current_num_known_descendents = cats->count() + items->count(); } } if (can_be_added) { mCategoryMap.insert(category_map_value_t( cat_id,LLCategoryData(cat_id, cb, version, current_num_known_descendents))); } return can_be_added; }
// Checked: 2010-02-28 (RLVa-1.1.3a) | Modified: RLVa-1.0.0h LLViewerInventoryCategory* RlvInventory::getSharedRoot() const { if (gInventory.isInventoryUsable()) { LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems; gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), pFolders, pItems); if (pFolders) { // NOTE: we might have multiple #RLV folders so we'll just go with the first one we come across LLViewerInventoryCategory* pFolder; for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++) { if ( ((pFolder = pFolders->get(idxFolder)) != NULL) && (RlvInventory::cstrSharedRoot == pFolder->getName()) ) return pFolder; } } } return NULL; }
BOOL LLInventoryFetchDescendentsObserver::isCategoryComplete(const LLViewerInventoryCategory* cat) const { const S32 version = cat->getVersion(); const S32 expected_num_descendents = cat->getDescendentCount(); if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) || (expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)) { return FALSE; } // it might be complete - check known descendents against // currently available. LLInventoryModel::cat_array_t* cats; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items); if (!cats || !items) { llwarns << "Category '" << cat->getName() << "' descendents corrupted, fetch failed." << llendl; // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean // that the cat just doesn't have any items or subfolders). // Unrecoverable, so just return done so that this observer can be cleared // from memory. return TRUE; } const S32 current_num_known_descendents = cats->count() + items->count(); // Got the number of descendents that we were expecting, so we're done. if (current_num_known_descendents == expected_num_descendents) { return TRUE; } // Error condition, but recoverable. This happens if something was added to the // category before it was initialized, so accountForUpdate didn't update descendent // count and thus the category thinks it has fewer descendents than it actually has. if (current_num_known_descendents >= expected_num_descendents) { llwarns << "Category '" << cat->getName() << "' expected descendentcount:" << expected_num_descendents << " descendents but got descendentcount:" << current_num_known_descendents << llendl; const_cast<LLViewerInventoryCategory *>(cat)->setDescendentCount(current_num_known_descendents); return TRUE; } return FALSE; }
LLUUID FSLSLBridge::findFSCategory() { if (!mBridgeFolderID.isNull()) { return mBridgeFolderID; } LLUUID fsCatID; LLUUID bridgeCatID; fsCatID = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); if (!fsCatID.isNull()) { LLInventoryModel::item_array_t* items; LLInventoryModel::cat_array_t* cats; gInventory.getDirectDescendentsOf(fsCatID, cats, items); if (cats) { S32 count = cats->count(); for (S32 i = 0; i < count; ++i) { if (cats->get(i)->getName() == FS_BRIDGE_FOLDER) { bridgeCatID = cats->get(i)->getUUID(); } } } } else { fsCatID = gInventory.createNewCategory(gInventory.getRootFolderID(), LLFolderType::FT_NONE, ROOT_FIRESTORM_FOLDER); } if (bridgeCatID.isNull()) { bridgeCatID = gInventory.createNewCategory(fsCatID, LLFolderType::FT_NONE, FS_BRIDGE_FOLDER); } mBridgeFolderID = bridgeCatID; return mBridgeFolderID; }
const LLUUID& get_folder_uuid(const LLUUID& parentFolderUUID, LLInventoryCollectFunctor& matchFunctor) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; gInventory.collectDescendentsIf(parentFolderUUID, cats, items, LLInventoryModel::EXCLUDE_TRASH, matchFunctor); S32 cats_count = cats.count(); if (cats_count > 1) { LL_WARNS("LLFriendCardsManager") << "There is more than one Friend card folder." << "The first folder will be used." << LL_ENDL; } return (cats_count >= 1) ? cats.get(0)->getUUID() : LLUUID::null; }
void LLFloaterOutbox::updateFolderCount() { S32 item_count = 0; if (mOutboxId.notNull()) { LLInventoryModel::cat_array_t * cats; LLInventoryModel::item_array_t * items; gInventory.getDirectDescendentsOf(mOutboxId, cats, items); item_count = cats->count() + items->count(); } mOutboxItemCount = item_count; if (!mImportBusy) { updateFolderCountStatus(); } }
void LLCOFMgr::checkCOF() { const LLUUID idCOF = getCOF(); const LLUUID idLAF = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); // Check COF for non-links and move them to Lost&Found LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems; gInventory.getDirectDescendentsOf(idCOF, pFolders, pItems); for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++) { LLViewerInventoryCategory* pFolder = pFolders->get(idxFolder).get(); if ( (pFolder) && (idLAF.notNull()) ) change_category_parent(&gInventory, pFolder, idLAF, false); } for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++) { LLViewerInventoryItem* pItem = pItems->get(idxItem).get(); if ( (pItem) && (!pItem->getIsLinkType()) && (idLAF.notNull()) ) change_item_parent(&gInventory, pItem, idLAF, false); } }
// Checked: 2010-08-30 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c bool RlvInventory::getPath(const uuid_vec_t& idItems, LLInventoryModel::cat_array_t& folders) const { // Sanity check - can't do anything without a shared root const LLViewerInventoryCategory* pRlvRoot = RlvInventory::instance().getSharedRoot(); if (!pRlvRoot) return false; folders.clear(); for (uuid_vec_t::const_iterator itItem = idItems.begin(); itItem != idItems.end(); ++itItem) { const LLInventoryItem* pItem = gInventory.getItem(*itItem); if ( (pItem) && (gInventory.isObjectDescendentOf(pItem->getUUID(), pRlvRoot->getUUID())) ) { // If the containing folder is a folded folder we need its parent LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); if (RlvInventory::instance().isFoldedFolder(pFolder, true)) pFolder = gInventory.getCategory(pFolder->getParentUUID()); folders.push_back(pFolder); } } return (folders.count() != 0); }
void LLPanelLandmarkInfo::populateFoldersList() { // Collect all folders that can contain landmarks. LLInventoryModel::cat_array_t cats; collectLandmarkFolders(cats); mFolderCombo->removeall(); // Put the "Landmarks" folder first in list. LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); const LLViewerInventoryCategory* lmcat = gInventory.getCategory(landmarks_id); if (!lmcat) { llwarns << "Cannot find the landmarks folder" << llendl; } else { std::string cat_full_name = getFullFolderName(lmcat); mFolderCombo->add(cat_full_name, lmcat->getUUID()); } typedef std::vector<folder_pair_t> folder_vec_t; folder_vec_t folders; // Sort the folders by their full name. for (S32 i = 0; i < cats.count(); i++) { const LLViewerInventoryCategory* cat = cats.get(i); std::string cat_full_name = getFullFolderName(cat); folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name)); } sort(folders.begin(), folders.end(), cmp_folders); // Finally, populate the combobox. for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++) mFolderCombo->add(it->second, LLSD(it->first)); }
void LLInventoryCategoriesObserver::changed(U32 mask) { if (!mCategoryMap.size()) return; for (category_map_t::iterator iter = mCategoryMap.begin(); iter != mCategoryMap.end(); ++iter) { const LLUUID& cat_id = (*iter).first; LLViewerInventoryCategory* category = gInventory.getCategory(cat_id); if (!category) continue; const S32 version = category->getVersion(); const S32 expected_num_descendents = category->getDescendentCount(); if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) || (expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)) { continue; } // Check number of known descendents to find out whether it has changed. LLInventoryModel::cat_array_t* cats; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(cat_id, cats, items); if (!cats || !items) { llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean // that the cat just doesn't have any items or subfolders). // Unrecoverable, so just skip this category. llassert(cats != NULL && items != NULL); continue; } const S32 current_num_known_descendents = cats->count() + items->count(); LLCategoryData& cat_data = (*iter).second; bool cat_changed = false; // If category version or descendents count has changed // update category data in mCategoryMap if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount) { cat_data.mVersion = version; cat_data.mDescendentsCount = current_num_known_descendents; cat_changed = true; } // If any item names have changed, update the name hash // Only need to check if (a) name hash has not previously been // computed, or (b) a name has changed. if (!cat_data.mIsNameHashInitialized || (mask & LLInventoryObserver::LABEL)) { LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cat_id); if (cat_data.mItemNameHash != item_name_hash) { cat_data.mIsNameHashInitialized = true; cat_data.mItemNameHash = item_name_hash; cat_changed = true; } } // If anything has changed above, fire the callback. if (cat_changed) cat_data.mCallback(); } }
bool LLFriendCardsManager::isObjDirectDescendentOfCategory(const LLInventoryObject* obj, const LLViewerInventoryCategory* cat) const { // we need both params to proceed. if ( !obj || !cat ) return false; // Need to check that target category is in the Calling Card/Friends folder. // In other case function returns unpredictable result. if ( !isCategoryInFriendFolder(cat) ) return false; bool result = false; LLInventoryModel::item_array_t* items; LLInventoryModel::cat_array_t* cats; gInventory.lockDirectDescendentArrays(cat->getUUID(), cats, items); if ( items ) { if ( obj->getType() == LLAssetType::AT_CALLINGCARD ) { // For CALLINGCARD compare items by creator's id, if they are equal assume // that it is same card and return true. Note: UUID's of compared items // may be not equal. Also, we already know that obj should be type of LLInventoryItem, // but in case inventory database is broken check what dynamic_cast returns. const LLInventoryItem* item = dynamic_cast < const LLInventoryItem* > (obj); if ( item ) { LLUUID creator_id = item->getCreatorUUID(); LLViewerInventoryItem* cur_item = NULL; for ( S32 i = items->count() - 1; i >= 0; --i ) { cur_item = items->get(i); if ( creator_id == cur_item->getCreatorUUID() ) { result = true; break; } } } } else { // Else check that items have same type and name. // Note: UUID's of compared items also may be not equal. std::string obj_name = obj->getName(); LLViewerInventoryItem* cur_item = NULL; for ( S32 i = items->count() - 1; i >= 0; --i ) { cur_item = items->get(i); if ( obj->getType() != cur_item->getType() ) continue; if ( obj_name == cur_item->getName() ) { result = true; break; } } } } if ( !result && cats ) { // There is no direct descendent in items, so check categories. // If target obj and descendent category have same type and name // then return true. Note: UUID's of compared items also may be not equal. std::string obj_name = obj->getName(); LLViewerInventoryCategory* cur_cat = NULL; for ( S32 i = cats->count() - 1; i >= 0; --i ) { cur_cat = cats->get(i); if ( obj->getType() != cur_cat->getType() ) continue; if ( obj_name == cur_cat->getName() ) { result = true; break; } } } gInventory.unlockDirectDescendentArrays(cat->getUUID()); return result; }