void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel::item_array_t& cof_items) { for (U32 i = 0; i < cof_items.size(); ++i) { LLViewerInventoryItem* item = cof_items.get(i); if (!item) continue; const LLAssetType::EType item_type = item->getType(); if (item_type == LLAssetType::AT_CLOTHING) continue; LLPanelInventoryListItemBase* item_panel = NULL; if (item_type == LLAssetType::AT_OBJECT) { item_panel = buildAttachemntListItem(item); mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false); } else if (item_type == LLAssetType::AT_BODYPART) { item_panel = buildBodypartListItem(item); if (!item_panel) continue; mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false); } } if (mAttachments->size()) { mAttachments->sort(); mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false) } else { mAttachments->setNoItemsCommentText(LLTrans::getString("no_attachments")); } if (mBodyParts->size()) { mBodyParts->sort(); mBodyParts->notify(REARRANGE); } }
// static void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data) { //llinfos << "LLFloaterProperties::onCommitName()" << llendl; LLFloaterProperties* self = (LLFloaterProperties*)data; if(!self) { return; } LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem(); if(!item) { return; } LLLineEditor* labelItemName = self->getChild<LLLineEditor>("LabelItemName"); if(labelItemName&& (item->getName() != labelItemName->getText()) && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) ) { LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->rename(labelItemName->getText()); if(self->mObjectID.isNull()) { new_item->updateServer(FALSE); gInventory.updateItem(new_item); gInventory.notifyObservers(); } else { LLViewerObject* object = gObjectList.findObject(self->mObjectID); if(object) { object->updateInventory( new_item, TASK_INVENTORY_ITEM_KEY, false); } } } }
void updateMenuItemsVisibility(LLContextMenu* menu) { bool bp_selected = false; // true if body parts selected bool clothes_selected = false; bool attachments_selected = false; // See what types of wearables are selected. for (uuid_vec_t::const_iterator it = mUUIDs.begin(); it != mUUIDs.end(); ++it) { LLViewerInventoryItem* item = gInventory.getItem(*it); if (!item) { llwarns << "Invalid item" << llendl; continue; } LLAssetType::EType type = item->getType(); if (type == LLAssetType::AT_CLOTHING) { clothes_selected = true; } else if (type == LLAssetType::AT_BODYPART) { bp_selected = true; } else if (type == LLAssetType::AT_OBJECT) { attachments_selected = true; } } // Enable/disable some menu items depending on the selection. bool allow_detach = !bp_selected && !clothes_selected && attachments_selected; bool allow_take_off = !bp_selected && clothes_selected && !attachments_selected; menu->setItemVisible("take_off", allow_take_off); menu->setItemVisible("detach", allow_detach); menu->setItemVisible("edit_outfit_separator", allow_take_off || allow_detach); }
void LLTracker::setLandmarkVisited() { // poke the inventory item if (!mTrackedLandmarkItemID.isNull()) { LLInventoryItem* i = gInventory.getItem( mTrackedLandmarkItemID ); LLViewerInventoryItem* item = (LLViewerInventoryItem*)i; if ( item && !(item->getFlags()&LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED)) { U32 flags = item->getFlags(); flags |= LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED; item->setFlags(flags); LLMessageSystem* msg = gMessageSystem; msg->newMessage("ChangeInventoryItemFlags"); msg->nextBlock("AgentData"); msg->addUUID("AgentID", gAgent.getID()); msg->addUUID("SessionID", gAgent.getSessionID()); msg->nextBlock("InventoryData"); msg->addUUID("ItemID", mTrackedLandmarkItemID); msg->addU32("Flags", flags); gAgent.sendReliableMessage(); LLInventoryModel::LLCategoryUpdate up(item->getParentUUID(), 0); gInventory.accountForUpdate(up); // need to communicate that the icon needs to change... gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item->getUUID()); gInventory.notifyObservers(); } } }
// static void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::string& joint_name) { LLViewerJointAttachment* attachmentp = NULL; for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); iter != gAgentAvatarp->mAttachmentPoints.end(); ) { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; if (attachment->getName() == joint_name) { attachmentp = attachment; break; } } if (attachmentp == NULL) { return; } for (uuid_vec_t::const_iterator it = items.begin(); it != items.end(); ++it) { const LLUUID &id = *it; LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getLinkedItem(id); if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) { rez_attachment(item, attachmentp); } else if(item && item->isFinished()) { // must be in library. copy it to our inventory and put it on. LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp); copy_inventory_item(gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(), LLUUID::null, std::string(), cb); } } }
void LLInventoryFetchObserver::fetchItems( const LLInventoryFetchObserver::item_ref_t& ids) { LLUUID owner_id; LLSD items_llsd; for(item_ref_t::const_iterator it = ids.begin(); it < ids.end(); ++it) { LLViewerInventoryItem* item = gInventory.getItem(*it); if(item) { if(item->isComplete()) { // It's complete, so put it on the complete container. mComplete.push_back(*it); continue; } else { owner_id = item->getPermissions().getOwner(); } } else { // assume it's agent inventory. owner_id = gAgent.getID(); } // It's incomplete, so put it on the incomplete container, and // pack this on the message. mIncomplete.push_back(*it); // Prepare the data to fetch LLSD item_entry; item_entry["owner_id"] = owner_id; item_entry["item_id"] = (*it); items_llsd.append(item_entry); } fetch_items_from_llsd(items_llsd); }
// static void LLWLParamManager::loadWindlightNotecard(LLVFS *vfs, const LLUUID& asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status) { LLUUID inventory_id(*((LLUUID*)user_data)); std::string name = "WindLight Setting.wl"; LLViewerInventoryItem *item = gInventory.getItem(inventory_id); if(item) { inventory_id = item->getUUID(); name = item->getName(); } if(LL_ERR_NOERR == status) { LLVFile file(vfs, asset_id, asset_type, LLVFile::READ); S32 file_length = file.getSize(); std::vector<char> buffer(file_length + 1); file.read((U8*)&buffer[0], file_length); buffer[file_length] = 0; LLNotecard notecard(LLNotecard::MAX_SIZE); LLMemoryStream str((U8*)&buffer[0], file_length + 1); notecard.importStream(str); std::string settings = notecard.getText(); LLMemoryStream settings_str((U8*)settings.c_str(), settings.length()); LLWLParamKey key((" Notecard: " + name), LLEnvKey::SCOPE_LOCAL); bool is_real_setting = getInstance()->loadPresetXML(key, settings_str); if(!is_real_setting) { LLSD subs; subs["NAME"] = name; LLNotifications::getInstance()->add("KittyInvalidWindlightNotecard", subs); } else { // We can do this because we know mCurParams getInstance()->mParamList[key].mInventoryID = inventory_id; LLEnvManagerNew::instance().setUseSkyPreset(key.name); } } }
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); } }
void FSLSLBridgeScriptCallback::fire(const LLUUID& inv_item) { if (inv_item.isNull() || !FSLSLBridge::instance().getBridgeCreating()) return; LLViewerInventoryItem* item = gInventory.getItem(inv_item); if (!item) { return; } gInventory.updateItem(item); gInventory.notifyObservers(); LLViewerObject* obj = gAgentAvatarp->getWornAttachment(FSLSLBridge::instance().getBridge()->getUUID()); //caps import std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgent"); std::string isMono = "lsl2"; //could also be "mono" if (!url.empty() && obj != NULL) { const std::string fName = prepUploadFile(); LLLiveLSLEditor::uploadAssetViaCapsStatic(url, fName, obj->getID(), inv_item, isMono, true); llinfos << "updating script ID for bridge" << llendl; FSLSLBridge::instance().mScriptItemID = inv_item; } else { //can't complete bridge creation - detach and remove object, remove script //try to clean up and go away. Fail. LLVOAvatarSelf::detachAttachmentIntoInventory(FSLSLBridge::instance().getBridge()->getUUID()); FSLSLBridge::instance().cleanUpBridge(); //also clean up script remains gInventory.purgeObject(item->getUUID()); gInventory.notifyObservers(); return; } }
void FSLSLBridge::processDetach(LLViewerObject* object, const LLViewerJointAttachment* attachment) { llinfos << "Entering processDetach" << llendl; if (gAgentAvatarp.isNull() || (!gAgentAvatarp->isSelf()) || (attachment == NULL) || (attachment->getName() != "Bridge")) { llwarns << "Couldn't detach bridge, object has wrong name or avatar wasn't self." << llendl; return; } LLViewerInventoryItem* fsObject = gInventory.getItem(object->getAttachmentItemID()); if (fsObject == NULL) //just in case { llwarns << "Couldn't detach bridge. inventory object was NULL." << llendl; return; } //is it in the right place? LLUUID catID = findFSCategory(); if (catID != fsObject->getParentUUID()) { //that was in the wrong place. It's not ours. llwarns << "Bridge seems to be the wrong inventory category. Aborting detachment." << llendl; return; } if (mpBridge != NULL && mpBridge->getUUID() == fsObject->getUUID()) { mpBridge = NULL; reportToNearbyChat(LLTrans::getString("fsbridge_detached")); mIsFirstCallDone = false; if (mBridgeCreating) { reportToNearbyChat(LLTrans::getString("fsbridge_warning_not_finished")); mBridgeCreating = false; //in case we interrupted the creation } } llinfos << "processDetach Finished" << llendl; }
// private void LLViewerGesture::doTrigger( BOOL send_chat ) { if (mSoundItemID != LLUUID::null) { LLViewerInventoryItem *item; item = gInventory.getItem(mSoundItemID); if (item) { send_sound_trigger(item->getAssetUUID(), SOUND_VOLUME); } } if (!mAnimation.empty()) { // AFK animations trigger the special "away" state, which // includes agent control settings. JC if (mAnimation == "enter_away_from_keyboard_state" || mAnimation == "away") { gAgent.setAFK(); } else { LLUUID anim_id = gAnimLibrary.stringToAnimState(mAnimation); gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_START); } } bool handled = !cmd_line_chat(mOutputString, CHAT_TYPE_NORMAL); #if SHY_MOD //Command handler handled = handled || SHCommandHandler::handleCommand(true, mOutputString, gAgentID, gAgentAvatarp); #endif //shy_mod if (!handled && send_chat && !mOutputString.empty()) { // Don't play nodding animation, since that might not blend // with the gesture animation. gChatBar->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); } }
// Get wearable type of the given item. // // There is a special case: so-called "dummy items" // (i.e. the ones that are there just to indicate that you're not wearing // any wearables of the corresponding type. They are currently grayed out // and suffixed with "not worn"). // Those items don't have an UUID, but they do have an associated wearable type. // If the user has invoked context menu for such item, // we ignore the passed item_id and retrieve wearable type from the item. LLWearableType::EType getWearableType(const LLUUID& item_id) { if (!isDummyItem(item_id)) { LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); if (item && item->isWearableType()) { return item->getWearableType(); } } else if (mCOFWearables) // dummy item selected { LLPanelDummyClothingListItem* item; item = dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem()); if (item) { return item->getWearableType(); } } return LLWearableType::WT_NONE; }
// static void LLFloaterLandmark::onBtnDelete(void* userdata) { LLFloaterLandmark* self = (LLFloaterLandmark*)userdata; LLViewerInventoryItem* item = gInventory.getItem(self->mImageAssetID); if(item) { // Move the item to the trash LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); if (item->getParentUUID() != trash_id) { LLInventoryModel::update_list_t update; LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); update.push_back(old_folder); LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1); update.push_back(new_folder); gInventory.accountForUpdate(update); LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->setParent(trash_id); // no need to restamp it though it's a move into trash because // it's a brand new item already. new_item->updateParentOnServer(FALSE); gInventory.updateItem(new_item); gInventory.notifyObservers(); } } // Delete the item entirely /* item->removeFromServer(); gInventory.deleteObject(item->getUUID()); gInventory.notifyObservers(); */ }
// //Bridge initialization // void FSLSLBridge::recreateBridge() { if (!gSavedSettings.getBOOL("UseLSLBridge")) { return; } if (gSavedSettings.getBOOL("NoInventoryLibrary")) { llwarns << "Asked to create bridge, but we don't have a library. Aborting." << llendl; reportToNearbyChat(LLTrans::getString("fsbridge_no_library")); mBridgeCreating = false; return; } if (mBridgeCreating) { llwarns << "Bridge creation already in progress, aborting new attempt." << llendl; reportToNearbyChat(LLTrans::getString("fsbridge_already_creating")); return; } LLUUID catID = findFSCategory(); LLViewerInventoryItem* fsBridge = findInvObject(mCurrentFullName, catID, LLAssetType::AT_OBJECT); if (fsBridge != NULL) { if (get_is_item_worn(fsBridge->getUUID())) { LLVOAvatarSelf::detachAttachmentIntoInventory(fsBridge->getUUID()); } } // clear the stored bridge ID - we are starting over. mpBridge = 0; //the object itself will get cleaned up when new one is created. initCreationStep(); }
// static void LLAssetIDAcquirer::handle(LLMessageSystem* mesgsys) { if(!mBusy) return; LLUUID agent_id; gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); if(agent_id != gAgent.getID()) return; S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData); for(int i = 0; i < num_wearables; i++) { U8 type_u8 = 0; gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i ); if(type_u8 == WT_UNDERPANTS) { LLUUID item_id; gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i ); LLUUID asset_id; gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i ); if(item_id == mItemID) { LLViewerInventoryItem* item = gInventory.getItem(item_id); if(item) { item->setAssetUUID(asset_id); } } // anyway // remove from queue std::vector<LLUUID>::iterator iter = std::find(mQueue.begin(), mQueue.end(), item_id); if(iter != mQueue.end()) mQueue.erase(iter); // continue mBusy = false; work(); } } }
void LLViewerInventoryCategory::createBasicHair() { LLUUID item_id = LLUUID("30d1d71b-38a6-4956-b27e-3bbcc17da0e2"); //lolhack, it's my UUID? //Make some hair just in case, using the library item so we're not hacking. LLUUID folder_id(gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART)); LLPermissions* perms = new LLPermissions(); perms->set(LLPermissions::DEFAULT); perms->setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, false); perms->setMaskBase(0); perms->setMaskEveryone(0); perms->setMaskGroup(0); perms->setMaskNext(0); perms->setMaskOwner(0); LLViewerInventoryItem* item = new LLViewerInventoryItem( item_id, folder_id, *perms, LLUUID("f0581d0d-d7c4-2573-b2ce-7a5d6ded3851"), LLAssetType::AT_BODYPART, LLInventoryType::IT_WEARABLE, "RuthHairFix", "", LLSaleInfo::DEFAULT, 0, 0); //Update some stuff I guess LLInventoryModel::update_map_t update; ++update[item->getParentUUID()]; gInventory.accountForUpdate(update); gInventory.updateItem(item); gInventory.notifyObservers(); wear_inventory_item_on_avatar(item); }
void FSLSLBridge::createNewBridge() { //check if user has a bridge LLUUID catID = findFSCategory(); //attach the Linden rock from the library (will resize as soon as attached) LLUUID libID = gInventory.getLibraryRootFolderID(); LLViewerInventoryItem* libRock = findInvObject(LIB_ROCK_NAME, libID, LLAssetType::AT_OBJECT); //shouldn't happen but just in case if (libRock != NULL) { //copy the library item to inventory and put it on LLPointer<LLInventoryCallback> cb = new FSLSLBridgeRezCallback(); llinfos << "Cloning a new Bridge container from the Library..." << llendl; copy_inventory_item(gAgent.getID(), libRock->getPermissions().getOwner(), libRock->getUUID(), catID, mCurrentFullName, cb); } else { llwarns << "Bridge container not found in the Library!" << llendl; // AH: Set to false or we won't be able to start another bridge creation // process in this session! mBridgeCreating = false; } }
void LLOutfitsList::onCOFChanged() { LLInventoryModel::changed_items_t changed_linked_items; const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs(); for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items.begin(); iter != changed_items.end(); ++iter) { LLViewerInventoryItem* item = gInventory.getItem(*iter); if (item) { // From gInventory we get the UUIDs of new links added to COF // or removed from COF. These links UUIDs are not the same UUIDs // that we have in each wearable items list. So we collect base items // UUIDs to find all items or links that point to same base items in wearable // items lists and update their worn state there. changed_linked_items.insert(item->getLinkedUUID()); } } for (outfits_map_t::iterator iter = mOutfitsMap.begin(); iter != mOutfitsMap.end(); ++iter) { LLAccordionCtrlTab* tab = iter->second; if (!tab) continue; LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); if (!list) continue; // Every list updates the labels of changed items or // the links that point to these items. list->updateChangedItems(changed_linked_items); } }
void LLFloaterProperties::onCommitDescription() { //llinfos << "LLFloaterProperties::onCommitDescription()" << llendl; LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); if(!item) return; LLLineEditor* labelItemDesc = getChild<LLLineEditor>("LabelItemDesc"); if(!labelItemDesc) { return; } if((item->getDescription() != labelItemDesc->getText()) && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))) { LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->setDescription(labelItemDesc->getText()); if(mObjectID.isNull()) { new_item->updateServer(FALSE); gInventory.updateItem(new_item); gInventory.notifyObservers(); } else { LLViewerObject* object = gObjectList.findObject(mObjectID); if(object) { object->updateInventory( new_item, TASK_INVENTORY_ITEM_KEY, false); } } } }
void CreateGestureCallback::fire(const LLUUID& inv_item) { if (inv_item.isNull()) return; gGestureManager.activateGesture(inv_item); LLViewerInventoryItem* item = gInventory.getItem(inv_item); if (!item) return; gInventory.updateItem(item); gInventory.notifyObservers(); if(!LLPreview::show(inv_item,FALSE)) { LLPreviewGesture* preview = LLPreviewGesture::show(std::string("Gesture: ") + item->getName(), inv_item, LLUUID::null); // Force to be entirely onscreen. gFloaterView->adjustToFitScreen(preview, FALSE); } }
void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item) { if (item == "landmark") { // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) { // [/RLVa:KB] LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos(); if(landmark == NULL) { LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); } else { LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "landmark").with("id",landmark->getUUID())); } // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 } // [/RLVa:KB] } else if (item == "copy") { // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) { // [/RLVa:KB] LLSLURL slurl; LLAgentUI::buildSLURL(slurl, false); LLUIString location_str(slurl.getSLURLString()); gClipboard.copyFromString(location_str); // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 } // [/RLVa:KB] } }
void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item) { if (item == "landmark") { LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos(); if(landmark == NULL) { LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); } else { LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "landmark").with("id",landmark->getUUID())); } } else if (item == "copy") { LLSLURL slurl; LLAgentUI::buildSLURL(slurl, false); LLUIString location_str(slurl.getSLURLString()); LLClipboard::instance().copyToClipboard(location_str,0,location_str.length()); } }
void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu) { if (!menu) { llwarns << "Invalid menu" << llendl; return; } const uuid_vec_t& ids = mUUIDs; // selected items IDs U32 mask = 0; // mask of selected items' types U32 n_items = ids.size(); // number of selected items U32 n_worn = 0; // number of worn items among the selected ones U32 n_already_worn = 0; // number of items worn of same type as selected items U32 n_links = 0; // number of links among the selected items U32 n_editable = 0; // number of editable items among the selected ones for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { LLUUID id = *it; LLViewerInventoryItem* item = gInventory.getItem(id); if (!item) { llwarns << "Invalid item" << llendl; // *NOTE: the logic below may not work in this case continue; } updateMask(mask, item->getType()); const LLWearableType::EType wearable_type = item->getWearableType(); const bool is_link = item->getIsLinkType(); const bool is_worn = get_is_item_worn(id); const bool is_editable = gAgentWearables.isWearableModifiable(id); const bool is_already_worn = gAgentWearables.selfHasWearable(wearable_type); if (is_worn) { ++n_worn; } if (is_editable) { ++n_editable; } if (is_link) { ++n_links; } if (is_already_worn) { ++n_already_worn; } } // for bool standalone = mParent ? mParent->isStandalone() : false; // *TODO: eliminate multiple traversals over the menu items setMenuItemVisible(menu, "wear_wear", n_already_worn == 0 && n_worn == 0); setMenuItemEnabled(menu, "wear_wear", n_already_worn == 0 && n_worn == 0); setMenuItemVisible(menu, "wear_add", mask == MASK_CLOTHING && n_worn == 0 && n_already_worn != 0); setMenuItemEnabled(menu, "wear_add", n_items == 1 && canAddWearable(ids.front()) && n_already_worn != 0); setMenuItemVisible(menu, "wear_replace", n_worn == 0 && n_already_worn != 0); //visible only when one item selected and this item is worn setMenuItemVisible(menu, "edit", !standalone && mask & (MASK_CLOTHING|MASK_BODYPART) && n_worn == n_items && n_worn == 1); setMenuItemEnabled(menu, "edit", n_editable == 1 && n_worn == 1 && n_items == 1); setMenuItemVisible(menu, "create_new", mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1); setMenuItemVisible(menu, "show_original", !standalone); setMenuItemEnabled(menu, "show_original", n_items == 1 && n_links == n_items); setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && n_worn == n_items); setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && n_worn == n_items); setMenuItemVisible(menu, "take_off_or_detach", mask == (MASK_ATTACHMENT|MASK_CLOTHING)); setMenuItemEnabled(menu, "take_off_or_detach", n_worn == n_items); setMenuItemVisible(menu, "object_profile", !standalone); setMenuItemEnabled(menu, "object_profile", n_items == 1); setMenuItemVisible(menu, "--no options--", FALSE); setMenuItemEnabled(menu, "--no options--", FALSE); // Populate or hide the "Attach to..." / "Attach to HUD..." submenus. if (mask == MASK_ATTACHMENT && n_worn == 0) { LLViewerAttachMenu::populateMenus("wearable_attach_to", "wearable_attach_to_hud"); } else { setMenuItemVisible(menu, "wearable_attach_to", false); setMenuItemVisible(menu, "wearable_attach_to_hud", false); } if (mask & MASK_UNKNOWN) { llwarns << "Non-wearable items passed." << llendl; } U32 num_visible_items = 0; for (U32 menu_item_index = 0; menu_item_index < menu->getItemCount(); ++menu_item_index) { const LLMenuItemGL* menu_item = menu->getItem(menu_item_index); if (menu_item && menu_item->getVisible()) { num_visible_items++; } } if (num_visible_items == 0) { setMenuItemVisible(menu, "--no options--", TRUE); } }
//virtual void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) { llinfos << "LLUpdateAgentInventoryResponder::result from capabilities" << llendl; LLUUID item_id = mPostData["item_id"]; LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(item_id); if(!item) { llwarns << "Inventory item for " << mVFileID << " is no longer in agent inventory." << llendl; return; } // Update viewer inventory item LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->setAssetUUID(content["new_asset"].asUUID()); gInventory.updateItem(new_item); gInventory.notifyObservers(); llinfos << "Inventory item " << item->getName() << " saved into " << content["new_asset"].asString() << llendl; LLInventoryType::EType inventory_type = new_item->getInventoryType(); switch(inventory_type) { case LLInventoryType::IT_NOTECARD: { // Update the UI with the new asset. LLPreviewNotecard* nc; nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID()); if(nc) { // *HACK: we have to delete the asset in the VFS so // that the viewer will redownload it. This is only // really necessary if the asset had to be modified by // the uploader, so this can be optimized away in some // cases. A better design is to have a new uuid if the // script actually changed the asset. if(nc->hasEmbeddedInventory()) { gVFS->removeFile( content["new_asset"].asUUID(), LLAssetType::AT_NOTECARD); } nc->refreshFromInventory(); } } break; case LLInventoryType::IT_LSL: { // Find our window and close it if requested. LLPreviewLSL* preview = (LLPreviewLSL*)LLPreview::find(item_id); if (preview) { // Bytecode save completed if (content["compiled"]) { preview->callbackLSLCompileSucceeded(); } else { preview->callbackLSLCompileFailed(content["errors"]); } } } break; case LLInventoryType::IT_GESTURE: { // If this gesture is active, then we need to update the in-memory // active map with the new pointer. if (gGestureManager.isGestureActive(item_id)) { LLUUID asset_id = new_item->getAssetUUID(); gGestureManager.replaceGesture(item_id, asset_id); gInventory.notifyObservers(); } //gesture will have a new asset_id LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id); if(previewp) { previewp->onUpdateSucceeded(); } } break; case LLInventoryType::IT_WEARABLE: default: break; } }
void LLLocalInventory::open(LLUUID item_id) { LLViewerInventoryItem* item = gInventory.getItem(item_id); if(!item) { llwarns << "Trying to open non-existent item" << llendl; return; } LLAssetType::EType type = item->getType(); if(type == LLAssetType::AT_SOUND) { S32 left, top; gFloaterView->getNewFloaterPosition(&left, &top); LLRect rect = gSavedSettings.getRect("PreviewSoundRect"); rect.translate(left - rect.mLeft, top - rect.mTop); LLPreviewSound* floaterp; floaterp = new LLPreviewSound("Preview sound", rect, "", item_id); floaterp->setFocus(TRUE); gFloaterView->adjustToFitScreen(floaterp, FALSE); } else if(type == LLAssetType::AT_ANIMATION) { S32 left, top; gFloaterView->getNewFloaterPosition(&left, &top); LLRect rect = gSavedSettings.getRect("PreviewAnimRect"); rect.translate(left - rect.mLeft, top - rect.mTop); LLPreviewAnim* floaterp; floaterp = new LLPreviewAnim("Preview anim", rect, "", item_id, LLPreviewAnim::NONE); floaterp->setFocus(TRUE); gFloaterView->adjustToFitScreen(floaterp, FALSE); } else if(type == LLAssetType::AT_TEXTURE) { S32 left, top; gFloaterView->getNewFloaterPosition(&left, &top); LLRect rect = gSavedSettings.getRect("PreviewTextureRect"); rect.translate( left - rect.mLeft, top - rect.mTop ); LLPreviewTexture* preview; preview = new LLPreviewTexture("preview texture", rect, "Preview texture", item_id, LLUUID::null, FALSE); //preview->setSourceID(source_id); preview->setFocus(TRUE); gFloaterView->adjustToFitScreen(preview, FALSE); } else if(type == LLAssetType::AT_GESTURE) { // If only the others were like this LLPreviewGesture::show("preview gesture", item_id, LLUUID::null, TRUE); } else if(type == LLAssetType::AT_LANDMARK) { S32 left, top; gFloaterView->getNewFloaterPosition(&left, &top); LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect"); rect.translate( left - rect.mLeft, top - rect.mTop ); LLPreviewLandmark* preview; preview = new LLPreviewLandmark("preview landmark", rect, "Preview landmark", item_id); preview->setFocus(TRUE); gFloaterView->adjustToFitScreen(preview, FALSE); } else { llwarns << "Dunno how to open type " << type << llendl; } }
void LLPreviewGesture::saveIfNeeded() { if (!gAssetStorage) { llwarns << "Can't save gesture, no asset storage system." << llendl; return; } if (!mDirty) { return; } // Copy the UI into a gesture LLMultiGesture* gesture = createGesture(); // Serialize the gesture S32 max_size = gesture->getMaxSerialSize(); char* buffer = new char[max_size]; LLDataPackerAsciiBuffer dp(buffer, max_size); BOOL ok = gesture->serialize(dp); if (dp.getCurrentSize() > 1000) { LLNotifications::instance().add("GestureSaveFailedTooManySteps"); delete gesture; gesture = NULL; } else if (!ok) { LLNotifications::instance().add("GestureSaveFailedTryAgain"); delete gesture; gesture = NULL; } else { // Every save gets a new UUID. Yup. LLTransactionID tid; LLAssetID asset_id; tid.generate(); asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); LLVFile file(gVFS, asset_id, LLAssetType::AT_GESTURE, LLVFile::APPEND); S32 size = dp.getCurrentSize(); file.setMaxSize(size); file.write((U8*)buffer, size); BOOL delayedUpload = FALSE; // Upload that asset to the database LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem(); if (item) { std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory"); std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory"); if (mObjectUUID.isNull() && !agent_url.empty()) { //need to disable the preview floater so item //isn't re-saved before new asset arrives //fake out refresh. item->setComplete(FALSE); refresh(); item->setComplete(TRUE); // Saving into agent inventory LLSD body; body["item_id"] = mItemUUID; LLHTTPClient::post(agent_url, body, new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); delayedUpload = TRUE; } else if (!mObjectUUID.isNull() && !task_url.empty()) { // Saving into task inventory LLSD body; body["task_id"] = mObjectUUID; body["item_id"] = mItemUUID; LLHTTPClient::post(task_url, body, new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); } else if (gAssetStorage) { LLLineEditor* descEditor = getChild<LLLineEditor>("desc"); LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE); } } // If this gesture is active, then we need to update the in-memory // active map with the new pointer. if (!delayedUpload && gGestureManager.isGestureActive(mItemUUID)) { // gesture manager now owns the pointer gGestureManager.replaceGesture(mItemUUID, gesture, asset_id); // replaceGesture may deactivate other gestures so let the // inventory know. gInventory.notifyObservers(); } else { // we're done with this gesture delete gesture; gesture = NULL; } mDirty = FALSE; // refresh will be called when callback // if triggered when delayedUpload if(!delayedUpload) { refresh(); } } delete [] buffer; buffer = NULL; }
void LLPreviewGesture::refresh() { // If previewing or item is incomplete, all controls are disabled LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem(); bool is_complete = (item && item->isComplete()) ? true : false; if (mPreviewGesture || !is_complete) { childSetEnabled("desc", FALSE); //mDescEditor->setEnabled(FALSE); mTriggerEditor->setEnabled(FALSE); mReplaceText->setEnabled(FALSE); mReplaceEditor->setEnabled(FALSE); mModifierCombo->setEnabled(FALSE); mKeyCombo->setEnabled(FALSE); mLibraryList->setEnabled(FALSE); mAddBtn->setEnabled(FALSE); mUpBtn->setEnabled(FALSE); mDownBtn->setEnabled(FALSE); mDeleteBtn->setEnabled(FALSE); mStepList->setEnabled(FALSE); mOptionsText->setEnabled(FALSE); mAnimationCombo->setEnabled(FALSE); mAnimationRadio->setEnabled(FALSE); mSoundCombo->setEnabled(FALSE); mChatEditor->setEnabled(FALSE); mWaitAnimCheck->setEnabled(FALSE); mWaitTimeCheck->setEnabled(FALSE); mWaitTimeEditor->setEnabled(FALSE); mActiveCheck->setEnabled(FALSE); mSaveBtn->setEnabled(FALSE); // Make sure preview button is enabled, so we can stop it mPreviewBtn->setEnabled(TRUE); return; } BOOL modifiable = item->getPermissions().allowModifyBy(gAgent.getID()); childSetEnabled("desc", modifiable); mTriggerEditor->setEnabled(TRUE); mLibraryList->setEnabled(modifiable); mStepList->setEnabled(modifiable); mOptionsText->setEnabled(modifiable); mAnimationCombo->setEnabled(modifiable); mAnimationRadio->setEnabled(modifiable); mSoundCombo->setEnabled(modifiable); mChatEditor->setEnabled(modifiable); mWaitAnimCheck->setEnabled(modifiable); mWaitTimeCheck->setEnabled(modifiable); mWaitTimeEditor->setEnabled(modifiable); mActiveCheck->setEnabled(TRUE); const std::string& trigger = mTriggerEditor->getText(); BOOL have_trigger = !trigger.empty(); const std::string& replace = mReplaceEditor->getText(); BOOL have_replace = !replace.empty(); LLScrollListItem* library_item = mLibraryList->getFirstSelected(); BOOL have_library = (library_item != NULL); LLScrollListItem* step_item = mStepList->getFirstSelected(); S32 step_index = mStepList->getFirstSelectedIndex(); S32 step_count = mStepList->getItemCount(); BOOL have_step = (step_item != NULL); mReplaceText->setEnabled(have_trigger || have_replace); mReplaceEditor->setEnabled(have_trigger || have_replace); mModifierCombo->setEnabled(TRUE); mKeyCombo->setEnabled(TRUE); mAddBtn->setEnabled(modifiable && have_library); mUpBtn->setEnabled(modifiable && have_step && step_index > 0); mDownBtn->setEnabled(modifiable && have_step && step_index < step_count-1); mDeleteBtn->setEnabled(modifiable && have_step); // Assume all not visible mAnimationCombo->setVisible(FALSE); mAnimationRadio->setVisible(FALSE); mSoundCombo->setVisible(FALSE); mChatEditor->setVisible(FALSE); mWaitAnimCheck->setVisible(FALSE); mWaitTimeCheck->setVisible(FALSE); mWaitTimeEditor->setVisible(FALSE); if (have_step) { // figure out the type, show proper options, update text LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); EStepType type = step->getType(); switch(type) { case STEP_ANIMATION: { LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; mOptionsText->setText("Animation to play:"); mAnimationCombo->setVisible(TRUE); mAnimationRadio->setVisible(TRUE); mAnimationRadio->setSelectedIndex((anim_step->mFlags & ANIM_FLAG_STOP) ? 1 : 0); mAnimationCombo->setCurrentByID(anim_step->mAnimAssetID); break; } case STEP_SOUND: { LLGestureStepSound* sound_step = (LLGestureStepSound*)step; mOptionsText->setText("Sound to play:"); mSoundCombo->setVisible(TRUE); mSoundCombo->setCurrentByID(sound_step->mSoundAssetID); break; } case STEP_CHAT: { LLGestureStepChat* chat_step = (LLGestureStepChat*)step; mOptionsText->setText("Chat to say:"); mChatEditor->setVisible(TRUE); mChatEditor->setText(chat_step->mChatText); break; } case STEP_WAIT: { LLGestureStepWait* wait_step = (LLGestureStepWait*)step; mOptionsText->setText("Wait:"); mWaitAnimCheck->setVisible(TRUE); mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM); mWaitTimeCheck->setVisible(TRUE); mWaitTimeCheck->set(wait_step->mFlags & WAIT_FLAG_TIME); mWaitTimeEditor->setVisible(TRUE); char buffer[16]; /*Flawfinder: ignore*/ snprintf(buffer, sizeof(buffer), "%.1f", (double)wait_step->mWaitSeconds); /* Flawfinder: ignore */ mWaitTimeEditor->setText(buffer); break; } default: break; } } else { // no gesture mOptionsText->setText(""); } BOOL active = gGestureManager.isGestureActive(mItemUUID); mActiveCheck->set(active); // Can only preview if there are steps mPreviewBtn->setEnabled(step_count > 0); // And can only save if changes have been made mSaveBtn->setEnabled(mDirty); addAnimations(); addSounds(); }
// static void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) { LLSaveNotecardInfo* info = static_cast<LLSaveNotecardInfo*>(user_data); if (0 == status) { if(info->mObjectUUID.isNull()) { LLViewerInventoryItem* item; item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID); if(item) { LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->setAssetUUID(asset_uuid); new_item->setTransactionID(info->mTransactionID); new_item->updateServer(FALSE); gInventory.updateItem(new_item); gInventory.notifyObservers(); } else { llwarns << "Inventory item for script " << info->mItemUUID << " is no longer in agent inventory." << llendl; } } else { LLViewerObject* object = gObjectList.findObject(info->mObjectUUID); LLViewerInventoryItem* item = NULL; if(object) { item = (LLViewerInventoryItem*)object->getInventoryObject(info->mItemUUID); } if(object && item) { item->setAssetUUID(asset_uuid); item->setTransactionID(info->mTransactionID); object->updateInventory(item, TASK_INVENTORY_ITEM_KEY, false); dialog_refresh_all(); } else { LLNotificationsUtil::add("SaveNotecardFailObjectNotFound"); } } // Perform item copy to inventory if (info->mCopyItem.notNull()) { if (LLViewerTextEditor* editor = info->mSelf->findChild<LLViewerTextEditor>("Notecard Editor")) { editor->copyInventory(info->mCopyItem); } } // Find our window and close it if requested. LLPreviewNotecard* previewp = (LLPreviewNotecard*)LLPreview::find(info->mItemUUID); if (previewp && previewp->mCloseAfterSave) { previewp->close(); } } else { llwarns << "Problem saving notecard: " << status << llendl; LLSD args; args["REASON"] = std::string(LLAssetStorage::getErrorString(status)); LLNotificationsUtil::add("SaveNotecardFailReason", args); } std::string uuid_string; asset_uuid.toString(uuid_string); std::string filename; filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string) + ".tmp"; LLFile::remove(filename); delete info; }
// TODO: This is very similar to LLPreviewNotecard::onSaveComplete. // Could merge code. // static void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) { LLSaveInfo* info = (LLSaveInfo*)user_data; if (info && (status == 0)) { if(info->mObjectUUID.isNull()) { // Saving into user inventory LLViewerInventoryItem* item; item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID); if(item) { LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->setDescription(info->mDesc); new_item->setTransactionID(info->mTransactionID); new_item->setAssetUUID(asset_uuid); new_item->updateServer(FALSE); gInventory.updateItem(new_item); gInventory.notifyObservers(); } else { llwarns << "Inventory item for gesture " << info->mItemUUID << " is no longer in agent inventory." << llendl; } } else { // Saving into in-world object inventory LLViewerObject* object = gObjectList.findObject(info->mObjectUUID); LLViewerInventoryItem* item = NULL; if(object) { item = (LLViewerInventoryItem*)object->getInventoryObject(info->mItemUUID); } if(object && item) { item->setDescription(info->mDesc); item->setAssetUUID(asset_uuid); item->setTransactionID(info->mTransactionID); object->updateInventory(item, TASK_INVENTORY_ITEM_KEY, false); dialog_refresh_all(); } else { LLNotifications::instance().add("GestureSaveFailedObjectNotFound"); } } // Find our window and close it if requested. LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(info->mItemUUID); if (previewp && previewp->mCloseAfterSave) { previewp->close(); } } else { llwarns << "Problem saving gesture: " << status << llendl; LLSD args; args["REASON"] = std::string(LLAssetStorage::getErrorString(status)); LLNotifications::instance().add("GestureSaveFailedReason", args); } delete info; info = NULL; }
// static LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID& item_id, const LLUUID& object_id, BOOL take_focus) { LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id); if (previewp) { previewp->open(); /*Flawfinder: ignore*/ if (take_focus) { previewp->setFocus(TRUE); } return previewp; } LLPreviewGesture* self = new LLPreviewGesture(); // Finish internal construction self->init(item_id, object_id); // Builds and adds to gFloaterView LLUICtrlFactory::getInstance()->buildFloater(self, "floater_preview_gesture.xml"); self->setTitle(title); // Move window to top-left of screen LLMultiFloater* hostp = self->getHost(); if (hostp == NULL) { LLRect r = self->getRect(); LLRect screen = gFloaterView->getRect(); r.setLeftTopAndSize(0, screen.getHeight(), r.getWidth(), r.getHeight()); self->setRect(r); } else { // re-add to host to update title hostp->addFloater(self, TRUE); } // Start speculative download of sounds and animations const LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_ANIMATION); LLInventoryModelBackgroundFetch::instance().start(animation_folder_id); const LLUUID sound_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SOUND); LLInventoryModelBackgroundFetch::instance().start(sound_folder_id); // this will call refresh when we have everything. LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem(); if(item && !item->isFinished()) { LLInventoryGestureAvailable* observer; observer = new LLInventoryGestureAvailable(); observer->watchItem(item_id); gInventory.addObserver(observer); item->fetchFromServer(); } else { // not sure this is necessary. self->refresh(); } if (take_focus) { self->setFocus(TRUE); } return self; }