// #include "llviewerprecompiledheaders.h" #include "lllocalinventory.h" #include "llviewerinventory.h" #include "llviewercontrol.h" #include "llpreviewsound.h" #include "llpreviewanim.h" #include "llpreviewtexture.h" #include "llpreviewgesture.h" #include "llpreviewlandmark.h" #include "dofloaterhex.h" #include "hgfloatertexteditor.h" #include "llappviewer.h" #include "lluictrlfactory.h" #include "llcombobox.h" #include "llnotificationsutil.h" #include "llagent.h" // gAgent #include "llviewerwindow.h" // alertXml LLUUID LLLocalInventory::addItem(std::string name, int type, LLUUID asset_id, bool open_automatically) { LLUUID item_id = addItem(name, type, asset_id); if(open_automatically) open(item_id); return item_id; } LLUUID LLLocalInventory::addItem(std::string name, int type, LLUUID asset_id) { LLUUID item_id; item_id.generate(); 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, gSystemFolderAssets, *perms, asset_id, (LLAssetType::EType)type, (LLInventoryType::EType)type, name, "", LLSaleInfo::DEFAULT, 0, time_corrected()); addItem(item); return item_id; } void LLLocalInventory::addItem(LLViewerInventoryItem* item) { //gInventory.addPretendItem(item); LLInventoryModel::update_map_t update; ++update[item->getParentUUID()]; gInventory.accountForUpdate(update); gInventory.updateItem(item); gInventory.notifyObservers(); } 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 << ", falling back to hex editor" << llendl; DOFloaterHex::show(item_id); } } //static void LLLocalInventory::loadInvCache(std::string filename) { std::string extension = gDirUtilp->getExtension(filename); std::string inv_filename = filename; if(extension == "gz") { LLUUID random; random.generate(); inv_filename = filename.substr(0, filename.length() - 3) + "." + random.asString(); if(!gunzip_file(filename, inv_filename)) { // failure... message? return; } } LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; bool is_cache_obsolete = false; if(LLInventoryModel::loadFromFile(inv_filename, cats, items, is_cache_obsolete)) { // create a container category for everything LLViewerInventoryCategory* container = new LLViewerInventoryCategory(gAgent.getID()); container->rename(gDirUtilp->getBaseFileName(filename, false)); LLUUID container_id; container_id.generate(); container->setUUID(container_id); container->setParent(gSystemFolderRoot); container->setPreferredType(LLFolderType::FT_NONE); LLInventoryModel::update_map_t container_update; ++container_update[container->getParentUUID()]; gInventory.accountForUpdate(container_update); gInventory.updateCategory(container); gInventory.notifyObservers(); LLViewerInventoryCategory* orphaned_items = new LLViewerInventoryCategory(gAgent.getID()); orphaned_items->rename("Orphaned Items"); LLUUID orphaned_items_id; orphaned_items_id.generate(); orphaned_items->setUUID(orphaned_items_id); orphaned_items->setParent(container_id); orphaned_items->setPreferredType(LLFolderType::FT_NONE); LLInventoryModel::update_map_t orphaned_items_update; ++orphaned_items_update[orphaned_items->getParentUUID()]; gInventory.accountForUpdate(orphaned_items_update); gInventory.updateCategory(orphaned_items); gInventory.notifyObservers(); //conflict handling std::map conflicting_cats; int dropped_cats = 0; int dropped_items = 0; // Add all categories LLInventoryModel::cat_array_t::iterator cat_iter = cats.begin(); LLInventoryModel::cat_array_t::iterator cat_end = cats.end(); for(; cat_iter != cat_end; ++cat_iter) { // Conditionally change its parent // Note: Should I search for missing parent id's? //if the parent is null, it goes in the very root of the tree! if((*cat_iter)->getParentUUID().isNull()) { (*cat_iter)->setParent(container_id); } // If the parent exists and outside of pretend inventory, generate a new uuid else if(gInventory.getCategory((*cat_iter)->getParentUUID())) { if(!gInventory.isObjectDescendentOf((*cat_iter)->getParentUUID(), gSystemFolderRoot, TRUE)) { std::map::iterator itr = conflicting_cats.find((*cat_iter)->getParentUUID()); if(itr == conflicting_cats.end()) { dropped_cats++; continue; } (*cat_iter)->setParent(itr->second); } } else { //well balls, this is orphaned. (*cat_iter)->setParent(orphaned_items_id); } // If this category already exists, generate a new uuid if(gInventory.getCategory((*cat_iter)->getUUID())) { LLUUID cat_random; cat_random.generate(); conflicting_cats[(*cat_iter)->getUUID()] = cat_random; (*cat_iter)->setUUID(cat_random); } LLInventoryModel::update_map_t update; ++update[(*cat_iter)->getParentUUID()]; gInventory.accountForUpdate(update); gInventory.updateCategory(*cat_iter); gInventory.notifyObservers(); } // Add all items LLInventoryModel::item_array_t::iterator item_iter = items.begin(); LLInventoryModel::item_array_t::iterator item_end = items.end(); for(; item_iter != item_end; ++item_iter) { // Conditionally change its parent // Note: Should I search for missing parent id's? //if the parent is null, it goes in the very root of the tree! if((*item_iter)->getParentUUID().isNull()) { (*item_iter)->setParent(container_id); } // If the parent exists and outside of pretend inventory, generate a new uuid if(gInventory.getCategory((*item_iter)->getParentUUID())) { if(!gInventory.isObjectDescendentOf((*item_iter)->getParentUUID(), gSystemFolderRoot, TRUE)) { std::map::iterator itr = conflicting_cats.find((*item_iter)->getParentUUID()); if(itr == conflicting_cats.end()) { dropped_items++; continue; } (*item_iter)->setParent(itr->second); } } else { //well balls, this is orphaned. (*item_iter)->setParent(orphaned_items_id); } // Avoid conflicts with real inventory... // If this item id already exists, generate a new uuid if(gInventory.getItem((*item_iter)->getUUID())) { LLUUID item_random; item_random.generate(); (*item_iter)->setUUID(item_random); } LLInventoryModel::update_map_t update; ++update[(*item_iter)->getParentUUID()]; gInventory.accountForUpdate(update); gInventory.updateItem(*item_iter); gInventory.notifyObservers(); } // Quality time if(dropped_items || dropped_cats) { std::ostringstream message; message << "Some items were ignored due to conflicts:\n\n"; if(dropped_cats) message << dropped_cats << " folders\n"; if(dropped_items) message << dropped_items << " items\n"; LLSD args; args["ERROR_MESSAGE"] = message.str(); LLNotificationsUtil::add("ErrorMessage", args); } conflicting_cats.clear();// srsly dont think this is need but w/e :D } // remove temporary unzipped file if(extension == "gz") { LLFile::remove(inv_filename); } } //static void LLLocalInventory::saveInvCache(std::string filename, LLFolderView* folder) { LLInventoryModel* model = &gInventory; std::set selected_items = folder->getSelectionList(); if(selected_items.size() < 1) { // No items selected? Wtfboom return; } LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; // Make complete lists of child categories and items std::set::iterator sel_iter = selected_items.begin(); std::set::iterator sel_end = selected_items.end(); for( ; sel_iter != sel_end; ++sel_iter) { LLInventoryCategory* cat = model->getCategory(*sel_iter); if(cat) { climb(cat, cats, items); } } // And what about items inside a folder that wasn't selected? // I guess I will just add selected items, so long as they aren't already added for(sel_iter = selected_items.begin(); sel_iter != sel_end; ++sel_iter) { LLInventoryItem* item = model->getItem(*sel_iter); if(item) { if(std::find(items.begin(), items.end(), item) == items.end()) { items.push_back(LLPointer((LLViewerInventoryItem*)item)); LLInventoryCategory* parent = model->getCategory(item->getParentUUID()); if(std::find(cats.begin(), cats.end(), parent) == cats.end()) { cats.push_back(LLPointer((LLViewerInventoryCategory*)parent)); } } } } LLInventoryModel::saveToFile(filename, cats, items); } // static void LLLocalInventory::climb(LLInventoryCategory* cat, LLInventoryModel::cat_array_t& cats, LLInventoryModel::item_array_t& items) { LLInventoryModel* model = &gInventory; // Add this category cats.push_back(LLPointer((LLViewerInventoryCategory*)cat)); LLInventoryModel::cat_array_t *direct_cats; LLInventoryModel::item_array_t *direct_items; model->getDirectDescendentsOf(cat->getUUID(), direct_cats, direct_items); // Add items LLInventoryModel::item_array_t::iterator item_iter = direct_items->begin(); LLInventoryModel::item_array_t::iterator item_end = direct_items->end(); for( ; item_iter != item_end; ++item_iter) { items.push_back(*item_iter); } // Do subcategories LLInventoryModel::cat_array_t::iterator cat_iter = direct_cats->begin(); LLInventoryModel::cat_array_t::iterator cat_end = direct_cats->end(); for( ; cat_iter != cat_end; ++cat_iter) { climb(*cat_iter, cats, items); } } LLUUID LLFloaterNewLocalInventory::sLastCreatorId = LLUUID::null; LLFloaterNewLocalInventory::LLFloaterNewLocalInventory() : LLFloater() { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_new_local_inventory.xml"); } LLFloaterNewLocalInventory::~LLFloaterNewLocalInventory() { } BOOL LLFloaterNewLocalInventory::postBuild(void) { // Fill in default values getChild("creator_id_line")->setText(std::string("00000000-0000-0000-0000-000000000000")); getChild("owner_id_line")->setText(gAgent.getID().asString()); getChild("asset_id_line")->setText(std::string("00000000-0000-0000-0000-000000000000")); getChild("name_line")->setText(std::string("")); getChild("desc_line")->setText(std::string("")); // Set up callbacks childSetAction("ok_btn", onClickOK, this); return TRUE; } // static void LLFloaterNewLocalInventory::onClickOK(void* user_data) { LLFloaterNewLocalInventory* floater = (LLFloaterNewLocalInventory*)user_data; LLUUID item_id; item_id.generate(); std::string name = floater->getChild("name_line")->getText(); std::string desc = floater->getChild("desc_line")->getText(); LLUUID asset_id = LLUUID(floater->getChild("asset_id_line")->getText()); LLUUID creator_id = LLUUID(floater->getChild("creator_id_line")->getText()); LLUUID owner_id = LLUUID(floater->getChild("owner_id_line")->getText()); LLAssetType::EType type = LLAssetType::lookup(floater->getChild("type_combo")->getValue().asString()); LLInventoryType::EType inv_type = LLInventoryType::IT_NONE; switch(type) { case LLAssetType::AT_TEXTURE: case LLAssetType::AT_TEXTURE_TGA: case LLAssetType::AT_IMAGE_TGA: case LLAssetType::AT_IMAGE_JPEG: inv_type = LLInventoryType::IT_TEXTURE; break; case LLAssetType::AT_SOUND: case LLAssetType::AT_SOUND_WAV: inv_type = LLInventoryType::IT_SOUND; break; case LLAssetType::AT_CALLINGCARD: inv_type = LLInventoryType::IT_CALLINGCARD; break; case LLAssetType::AT_LANDMARK: inv_type = LLInventoryType::IT_LANDMARK; break; case LLAssetType::AT_SCRIPT: inv_type = LLInventoryType::IT_LSL; break; case LLAssetType::AT_CLOTHING: inv_type = LLInventoryType::IT_WEARABLE; break; case LLAssetType::AT_OBJECT: inv_type = LLInventoryType::IT_OBJECT; break; case LLAssetType::AT_NOTECARD: inv_type = LLInventoryType::IT_NOTECARD; break; case LLAssetType::AT_CATEGORY: inv_type = LLInventoryType::IT_CATEGORY; break; //No longer asset types. /*case LLFolderType::FT_ROOT_CATEGORY: case LLFolderType::FT_TRASH: case LLFolderType::FT_SNAPSHOT_CATEGORY: case LLFolderType::FT_LOST_AND_FOUND: inv_type = LLInventoryType::IT_ROOT_CATEGORY; break;*/ case LLAssetType::AT_LSL_TEXT: case LLAssetType::AT_LSL_BYTECODE: inv_type = LLInventoryType::IT_LSL; break; case LLAssetType::AT_BODYPART: inv_type = LLInventoryType::IT_WEARABLE; break; case LLAssetType::AT_ANIMATION: inv_type = LLInventoryType::IT_ANIMATION; break; case LLAssetType::AT_GESTURE: inv_type = LLInventoryType::IT_GESTURE; break; //case LLAssetType::AT_SIMSTATE: default: //inv_type = LLInventoryType::IT_CALLINGCARD; break; } if(inv_type == LLInventoryType::IT_NONE) return; LLPermissions* perms = new LLPermissions(); perms->init(creator_id, owner_id, LLUUID::null, LLUUID::null); LLViewerInventoryItem* item = new LLViewerInventoryItem( item_id, gSystemFolderRoot, *perms, asset_id, type, inv_type, name, desc, LLSaleInfo::DEFAULT, 0, 0); LLLocalInventory::addItem(item); if(floater->childGetValue("chk_open")) { LLLocalInventory::open(item_id); } LLFloaterNewLocalInventory::sLastCreatorId = creator_id; floater->close(); } //