BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop) { BOOL rv = isInviteAllowed(); if(rv && category) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLUniqueBuddyCollector buddies; gInventory.collectDescendentsIf(category->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, buddies); S32 count = items.count(); if(count == 0) { rv = FALSE; } else if(drop) { uuid_vec_t ids; ids.reserve(count); for(S32 i = 0; i < count; ++i) { ids.push_back(items.get(i)->getCreatorUUID()); } inviteToSession(ids); } } return rv; }
BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop) { if (category) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLUniqueBuddyCollector buddies; gInventory.collectDescendentsIf(category->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, buddies); S32 count = items.count(); if(count == 0) { return false; } else if(drop) { LLDynamicArray<LLUUID> ids; for(S32 i = 0; i < count; ++i) { ids.put(items.get(i)->getCreatorUUID()); } inviteToSession(ids); } } return true; }
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(); } }
bool LLFriendCardsManager::isItemInAnyFriendsList(const LLViewerInventoryItem* item) { if (item->getType() != LLAssetType::AT_CALLINGCARD) return false; LLInventoryModel::item_array_t items; findMatchedFriendCards(item->getCreatorUUID(), items); return items.count() > 0; }
void LLFloaterWorldMap::buildLandmarkIDLists() { LLCtrlListInterface *list = childGetListInterface("landmark combo"); if (!list) { return; } // Delete all but the "None" entry S32 list_size = list->getItemCount(); if (list_size > 1) { list->selectItemRange(1, -1); list->operateOnSelection(LLCtrlListInterface::OP_DELETE); } mLandmarkItemIDList.reset(); mLandmarkAssetIDList.reset(); // Get all of the current landmarks mLandmarkAssetIDList.put( LLUUID::null ); mLandmarkItemIDList.put( LLUUID::null ); mLandmarkAssetIDList.put( sHomeID ); mLandmarkItemIDList.put( sHomeID ); LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLIsType is_landmark(LLAssetType::AT_LANDMARK); gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, is_landmark); std::sort(items.begin(), items.end(), LLViewerInventoryItem::comparePointers()); S32 count = items.count(); for(S32 i = 0; i < count; ++i) { LLInventoryItem* item = items.get(i); list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID()); mLandmarkAssetIDList.put( item->getAssetUUID() ); mLandmarkItemIDList.put( item->getUUID() ); } list->sortByColumn(std::string("landmark name"), TRUE); list->selectFirstItem(); }
void LLCOFMgr::removeCOFItemLinks(const LLUUID& idItem) { gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem); LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; gInventory.collectDescendents(getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH); for (S32 idxItem = 0; idxItem < items.count(); idxItem++) { const LLInventoryItem* pItem = items.get(idxItem).get(); if ( (pItem->getIsLinkType()) && (idItem == pItem->getLinkedUUID()) ) gInventory.purgeObject(pItem->getUUID()); } }
void LLCOFMgr::purgeBOFLink() { LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems; gInventory.getDirectDescendentsOf(getCOF(), pFolders, pItems); for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++) { const LLViewerInventoryItem* pItem = pItems->get(idxItem).get(); if ( (!pItem) || (LLAssetType::AT_LINK_FOLDER != pItem->getActualType()) ) continue; const LLViewerInventoryCategory* pLinkFolder = pItem->getLinkedCategory(); if ( (pLinkFolder) && (LLFolderType::FT_OUTFIT == pLinkFolder->getPreferredType()) ) gInventory.purgeObject(pItem->getUUID()); } }
// Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d S32 RlvInventory::getDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType filterType) { S32 cntType = 0; if (pFolder) { LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems; gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems); if (pItems) { for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++) if (pItems->get(idxItem)->getType() == filterType) cntType++; } } return cntType; }
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; }
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; }
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::synchWearables() { const LLUUID idCOF = getCOF(); // Grab all wearable links currently in COF LLInventoryModel::item_array_t items; getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_BODYPART, true); getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_CLOTHING, true); // Transform collection of link LLViewerInventory pointers into collection of target LLUUIDs uuid_vec_t curItems; for (S32 idxItem = 0; idxItem < items.count(); idxItem++) { const LLViewerInventoryItem* pItem = items.get(idxItem); if (!pItem) continue; curItems.push_back(pItem->getLinkedUUID()); } // Grab the item UUIDs of all currently worn wearables uuid_vec_t newItems; for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++) { const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)idxType); if (idItem.isNull()) continue; newItems.push_back(idItem); } uuid_vec_t addItems, remItems; LLCommonUtils::computeDifference(newItems, curItems, addItems, remItems); // Add links for worn wearables that aren't linked yet for (uuid_vec_t::const_iterator itItem = addItems.begin(); itItem != addItems.end(); ++itItem) addWearable(*itItem); // Remove links of wearables that aren't worn anymore for (uuid_vec_t::const_iterator itItem = remItems.begin(); itItem != remItems.end(); ++itItem) removeWearable(*itItem); }
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-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.0.0h void RlvInventory::fetchSharedLinks() { // TOFIX-RLVa: [RLVa-1.2.1] Finish adding support for AT_LINK_FOLDER const LLViewerInventoryCategory* pRlvRoot = getSharedRoot(); if (!pRlvRoot) return; // Grab all the inventory links under the shared root LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; RlvIsLinkType f; gInventory.collectDescendentsIf(pRlvRoot->getUUID(), folders, items, FALSE, f, FALSE); // Add them to the "to fetch" list based on link type uuid_vec_t idFolders, idItems; for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) { const LLViewerInventoryItem* pItem = items.get(idxItem); switch (pItem->getActualType()) { case LLAssetType::AT_LINK: idItems.push_back(pItem->getLinkedUUID()); break; case LLAssetType::AT_LINK_FOLDER: idFolders.push_back(pItem->getLinkedUUID()); break; default: break;; } } RLV_INFOS << "Starting link target fetch of " << idItems.size() << " items and " << idFolders.size() << " folders" << RLV_ENDL; // Fetch all the link item targets RlvItemFetcher itemFetcher(idItems); itemFetcher.startFetch(); // Fetch all the link folder targets // TODO! }
// Checked: 2010-03-14 (RLVa-1.1.3a) | Added: RLVa-1.2.0a void RlvRenameOnWearObserver::doneIdle() { const LLViewerInventoryCategory* pRlvRoot = NULL; LLVOAvatar* pAvatar = gAgentAvatarp; if ( (RlvSettings::getEnableSharedWear()) || (!RlvSettings::getSharedInvAutoRename()) || (LLStartUp::getStartupState() < STATE_STARTED) || (!pAvatar) || ((pRlvRoot = RlvInventory::instance().getSharedRoot()) == NULL) ) { delete this; return; } const LLViewerJointAttachment* pAttachPt = NULL; S32 idxAttachPt = 0; // RLV_ASSERT(mComplete.size() > 0); // Catch instances where we forgot to call startFetch() for (uuid_vec_t::const_iterator itItem = mComplete.begin(); itItem != mComplete.end(); ++itItem) { const LLUUID& idAttachItem = *itItem; // If the item resides under #RLV we'll rename it directly; otherwise settle for "renaming" all of its links residing under #RLV LLInventoryModel::item_array_t items; if (gInventory.isObjectDescendentOf(idAttachItem, pRlvRoot->getUUID())) items.push_back(gInventory.getItem(idAttachItem)); else items = gInventory.collectLinkedItems(idAttachItem, pRlvRoot->getUUID()); if (items.empty()) continue; if ( ((pAttachPt = pAvatar->getWornAttachmentPoint(idAttachItem)) == NULL) || ((idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(pAttachPt)) == 0) ) { // RLV_ASSERT(false); continue; } static const std::string &new_category_name = LLViewerFolderType::lookupNewCategoryName(LLFolderType::FT_NONE); for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) { LLViewerInventoryItem* pItem = items.get(idxItem); if (!pItem) continue; S32 idxAttachPtItem = RlvAttachPtLookup::getAttachPointIndex(pItem); if ( (idxAttachPt == idxAttachPtItem) || (idxAttachPtItem) ) continue; std::string strAttachPt = pAttachPt->getName(); LLStringUtil::toLower(strAttachPt); // If we can modify the item then we rename it directly, otherwise we create a new folder and move it if (pItem->getPermissions().allowModifyBy(gAgent.getID())) { std::string strName = pItem->getName(); LLStringUtil::truncate(strName, DB_INV_ITEM_NAME_STR_LEN - strAttachPt.length() - 3); strName += " (" + strAttachPt + ")"; pItem->rename(strName); pItem->updateServer(FALSE); gInventory.addChangedMask(LLInventoryObserver::LABEL, pItem->getUUID()); } else { // Don't do anything if the item is a direct descendant of the shared root, or a folded folder LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); if ( (pFolder) && (pFolder->getUUID() != pRlvRoot->getUUID()) && (!RlvInventory::isFoldedFolder(pFolder, false)) ) { std::string strFolderName = ".(" + strAttachPt + ")"; // Rename the item's parent folder if it's called "New Folder", isn't directly under #RLV and contains exactly 1 object if ( (new_category_name == pFolder->getName()) && (pFolder->getParentUUID() != pRlvRoot->getUUID()) && (1 == RlvInventory::getDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT)) ) { pFolder->rename(strFolderName); pFolder->updateServer(FALSE); gInventory.addChangedMask(LLInventoryObserver::LABEL, pFolder->getUUID()); } else { // "No modify" item with a non-renameable parent: create a new folder named and move the item into it LLUUID idAttachFolder = gInventory.createNewCategory(pFolder->getUUID(), LLFolderType::FT_NONE, strFolderName); move_inventory_item(gAgent.getID(), gAgent.getSessionID(), pItem->getUUID(), idAttachFolder, std::string(), NULL); } } } } } gInventory.notifyObservers(); delete this; }
// Checked: 2010-03-21 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAction eAction, EWearFlags eFlags) { // [See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items] if (!gAgentWearables.areWearablesLoaded()) { LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); return; } if (!isAgentAvatarValid()) return; // Grab a list of all the items we'll be wearing/attaching LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; RlvWearableItemCollector f(pFolder, eAction, eFlags); gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, f, TRUE); // TRUE if we've already encountered this LLWearableType::EType (used only on wear actions and only for AT_CLOTHING) bool fSeenWType[LLWearableType::WT_COUNT] = { false }; EWearAction eCurAction = eAction; for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) { LLViewerInventoryItem* pRlvItem = items.get(idxItem); LLViewerInventoryItem* pItem = (LLAssetType::AT_LINK == pRlvItem->getActualType()) ? pRlvItem->getLinkedItem() : pRlvItem; // If it's wearable it should be worn on detach // if ( (ACTION_DETACH == eAction) && (isWearableItem(pItem)) && (!isWearingItem(pItem)) ) // continue; // Each folder can specify its own EWearAction override if (isWearAction(eAction)) eCurAction = f.getWearAction(pRlvItem->getParentUUID()); else eCurAction = eAction; // NOTES: * if there are composite items then RlvWearableItemCollector made sure they can be worn (or taken off depending) // * some scripts issue @remattach=force,attach:worn-items=force so we need to attach items even if they're currently worn switch (pItem->getType()) { case LLAssetType::AT_BODYPART: RLV_ASSERT(isWearAction(eAction)); // RlvWearableItemCollector shouldn't be supplying us with body parts on detach case LLAssetType::AT_CLOTHING: if (isWearAction(eAction)) { // The first time we encounter any given clothing type we use 'eCurAction' (replace or add) // The second time we encounter a given clothing type we'll always add (rather than replace the previous iteration) eCurAction = (!fSeenWType[pItem->getWearableType()]) ? eCurAction : ACTION_WEAR_ADD; ERlvWearMask eWearMask = gRlvWearableLocks.canWear(pRlvItem); if ( ((ACTION_WEAR_REPLACE == eCurAction) && (eWearMask & RLV_WEAR_REPLACE)) || ((ACTION_WEAR_ADD == eCurAction) && (eWearMask & RLV_WEAR_ADD)) ) { // The check for whether we're replacing a currently worn composite item happens in onWearableArrived() if (!isAddWearable(pItem)) addWearable(pRlvItem, eCurAction); fSeenWType[pItem->getWearableType()] = true; } } else { const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(pItem->getUUID()); if ( (pWearable) && (isForceRemovable(pWearable, false)) ) remWearable(pWearable); } break; case LLAssetType::AT_OBJECT: if (isWearAction(eAction)) { ERlvWearMask eWearMask = gRlvAttachmentLocks.canAttach(pRlvItem); if ( ((ACTION_WEAR_REPLACE == eCurAction) && (eWearMask & RLV_WEAR_REPLACE)) || ((ACTION_WEAR_ADD == eCurAction) && (eWearMask & RLV_WEAR_ADD)) ) { if (!isAddAttachment(pRlvItem)) { #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS // We still need to check whether we're about to replace a currently worn composite item // (which we're not if we're just reattaching an attachment we're already wearing) LLViewerInventoryCategory* pCompositeFolder = NULL; if ( (pAttachPt->getObject()) && (RlvSettings::getEnableComposites()) && (pAttachPt->getItemID() != pItem->getUUID()) && (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pCompositeFolder)) ) { // If we can't take off the composite folder this item would replace then don't allow it to get attached if (gRlvHandler.canTakeOffComposite(pCompositeFolder)) { forceFolder(pCompositeFolder, ACTION_DETACH, FLAG_DEFAULT); addAttachment(pRlvItem); } } else #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS { addAttachment(pRlvItem, eCurAction); } } } } else { const LLViewerObject* pAttachObj = gAgentAvatarp->getWornAttachment(pItem->getUUID()); if ( (pAttachObj) && (isForceDetachable(pAttachObj, false)) ) remAttachment(pAttachObj); } break; #ifdef RLV_EXTENSION_FORCEWEAR_GESTURES case LLAssetType::AT_GESTURE: if (isWearAction(eAction)) { if (std::find_if(m_addGestures.begin(), m_addGestures.end(), RlvPredIsEqualOrLinkedItem(pRlvItem)) == m_addGestures.end()) m_addGestures.push_back(pRlvItem); } else { if (std::find_if(m_remGestures.begin(), m_remGestures.end(), RlvPredIsEqualOrLinkedItem(pRlvItem)) == m_remGestures.end()) m_remGestures.push_back(pRlvItem); } break; #endif // RLV_EXTENSION_FORCEWEAR_GESTURES default: break; } } }
void doneIdle() { uuid_vec_t idItems; // Add the link targets for COF LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; gInventory.collectDescendents(LLCOFMgr::getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH); for (S32 idxItem = 0; idxItem < items.count(); idxItem++) { const LLViewerInventoryItem* pItem = items.get(idxItem); if (!pItem) continue; idItems.push_back(pItem->getLinkedUUID()); } // Add all currently worn wearables for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++) { const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)idxType); if (idItem.isNull()) continue; idItems.push_back(idItem); } // Add all currently worn attachments const LLVOAvatar* pAvatar = gAgentAvatarp; if (pAvatar) { for (LLVOAvatar::attachment_map_t::const_iterator itAttachPt = pAvatar->mAttachmentPoints.begin(); itAttachPt != pAvatar->mAttachmentPoints.end(); ++itAttachPt) { const LLViewerJointAttachment* pAttachPt = itAttachPt->second; for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachment = pAttachPt->mAttachedObjects.begin(); itAttachment != pAttachPt->mAttachedObjects.end(); ++itAttachment) { const LLUUID& idItem = (*itAttachment)->getAttachmentItemID(); if (idItem.isNull()) continue; idItems.push_back(idItem); } } } // Fetch it all LLCOFLinkTargetFetcher* pFetcher = new LLCOFLinkTargetFetcher(idItems); pFetcher->startFetch(); if (pFetcher->isFinished()) { pFetcher->done(); } else { gInventory.addObserver(pFetcher); // It doesn't look like we *really* need the link targets so we can do a preliminary initialization now already LLCOFMgr::instance().setLinkAttachments(true); LLCOFMgr::instance().updateAttachments(); } delete this; }
void LLFloaterWorldMap::buildLandmarkIDLists() { LLCtrlListInterface *list = mListLandmarkCombo; if (!list) return; // Delete all but the "None" entry S32 list_size = list->getItemCount(); if (list_size > 1) { list->selectItemRange(1, -1); list->operateOnSelection(LLCtrlListInterface::OP_DELETE); } mLandmarkItemIDList.reset(); mLandmarkAssetIDList.reset(); // Get all of the current landmarks mLandmarkAssetIDList.put( LLUUID::null ); mLandmarkItemIDList.put( LLUUID::null ); mLandmarkAssetIDList.put( sHomeID ); mLandmarkItemIDList.put( sHomeID ); LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLIsType is_landmark(LLAssetType::AT_LANDMARK); gInventory.collectDescendentsIf(gInventory.getRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, is_landmark); std::sort(items.begin(), items.end(), LLViewerInventoryItem::comparePointers()); std::list<LLInventoryItem*> usedLMs; BOOL filterLandmarks = gSavedSettings.getBOOL("WorldmapFilterDuplicateLandmarks"); S32 count = items.count(); for(S32 i = 0; i < count; ++i) { LLInventoryItem* item = items.get(i); if (filterLandmarks) { bool skip = false; for (std::list<LLInventoryItem*>::iterator it = usedLMs.begin(); it != usedLMs.end(); ++it) { if ((*it)->getAssetUUID() == item->getAssetUUID()) { skip = true; break; } } if (skip) continue; usedLMs.push_front(item); } list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID()); mLandmarkAssetIDList.put( item->getAssetUUID() ); mLandmarkItemIDList.put( item->getUUID() ); } list->selectFirstItem(); }
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(); } }
void LLFloaterClothing::buildClothingList() { //llinfos << "buildClothingList" << llendl; LLScrollListCtrl* list = gUICtrlFactory->getScrollListByName(this, "clothing_list"); if (!list) return; list->operateOnAll(LLCtrlListInterface::OP_DELETE); LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLIsClothing is_clothing; gInventory.collectDescendentsIf(gAgent.getInventoryRootID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, is_clothing); S32 count = items.count(); for(S32 i = 0; i < count; ++i) { LLInventoryItem* item = items.get(i); LLSD row; row["id"] = item->getUUID(); BOOL item_is_multi = FALSE; if ( item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) { item_is_multi = TRUE; } LLUUID image_id = get_item_icon_uuid(item->getType(), item->getInventoryType(), item->getFlags(), item_is_multi); // flags = wearable type row["columns"][0]["column"] = "icon"; row["columns"][0]["type"] = "icon"; row["columns"][0]["value"] = image_id; LLString text = item->getName(); LLString style = "NORMAL"; if( gAgent.isWearingItem( item->getUUID() ) ) { text.append(" (worn)"); style = "BOLD"; } row["columns"][1]["column"] = "name"; row["columns"][1]["value"] = text; row["columns"][1]["font"] = "SANSSERIFSMALL"; row["columns"][1]["font-style"] = style; // hidden column for sorting U32 flags = item->getFlags(); // flags = wearable type enum EWearableType wearable_type = (enum EWearableType)flags; const char* wearable_label = LLWearable::typeToTypeLabel(wearable_type); //line->addColumn(wearable_label, FONT, -1); // invisible row["columns"][2]["column"] = "sort"; row["columns"][2]["value"] = wearable_label; list->addElement(row); } if (count > 0) { mAllowSelection = TRUE; } else if (LLInventoryModel::backgroundFetchActive()) { // We're loading list->addCommentText(LOADING_STRING); mAllowSelection = FALSE; } else { // Weird case, we're done loading but have no clothing list->addCommentText("No clothing found."); mAllowSelection = FALSE; } }
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; }