PageRenderTime 81ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llfloaterexportregion.cpp

https://github.com/electronbeam/Momentum
C++ | 429 lines | 340 code | 48 blank | 41 comment | 63 complexity | 3aad9a75621bf232d0e8fa31b70ac770 MD5 | raw file
  1. // <edit>
  2. #include "llviewerprecompiledheaders.h"
  3. #include "llfloaterexportregion.h"
  4. #include "llfloaterexport.h"
  5. #include "lluictrlfactory.h"
  6. #include "llsdutil.h"
  7. #include "llsdserialize.h"
  8. #include "llselectmgr.h"
  9. #include "llscrolllistctrl.h"
  10. #include "llchat.h"
  11. #include "llfloaterchat.h"
  12. #include "llfilepicker.h"
  13. #include "llagent.h"
  14. #include "llvoavatar.h"
  15. #include "llimportobject.h"
  16. #include "llviewerobjectlist.h"
  17. #include "llviewerregion.h"
  18. LLFloaterExportRegion* LLFloaterExportRegion::sInstance = NULL;
  19. LLFloaterExportRegion::LLFloaterExportRegion(const LLSD& unused)
  20. {
  21. sInstance = this;
  22. LLUICtrlFactory::getInstance()->buildFloater(this, "floater_export.xml");
  23. }
  24. LLFloaterExportRegion::~LLFloaterExportRegion()
  25. {
  26. sInstance = NULL;
  27. }
  28. BOOL LLFloaterExportRegion::postBuild(void)
  29. {
  30. LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
  31. LLViewerRegion* objregion = NULL;
  32. LLViewerRegion* agentregion = gAgent.getRegion();
  33. if(!agentregion) return TRUE;
  34. for (LLDynamicArrayPtr<LLPointer<LLViewerObject> >::iterator iter = gObjectList.getObjectMap().begin();
  35. iter != gObjectList.getObjectMap().end(); iter++)
  36. {
  37. LLViewerObject* objectp = (*iter);
  38. if(!objectp || objectp->isDead()) continue;
  39. objregion = objectp->getRegion();
  40. //if(!objregion || objregion->getHandle() != agentregion->getHandle()) continue;
  41. if(objectp->isAvatar() || objectp->isAttachment()) continue; //we dont want avatars right now...
  42. if(objectp->isRoot())
  43. {
  44. std::string objectp_id = llformat("%d", objectp->getLocalID());
  45. if(list->getItemIndex(objectp->getID()) == -1)
  46. {
  47. bool is_attachment = false;
  48. bool is_root = true;
  49. LLViewerObject* parentp = objectp->getSubParent();
  50. if(parentp)
  51. {
  52. if(!parentp->isAvatar())
  53. {
  54. // parent is a prim I guess
  55. is_root = false;
  56. }
  57. else
  58. {
  59. // parent is an avatar
  60. is_attachment = true;
  61. //if(!avatars[parentp]) avatars[parentp] = true;
  62. }
  63. }
  64. bool is_prim = true;
  65. if(objectp->getPCode() >= LL_PCODE_APP)
  66. {
  67. is_prim = false;
  68. }
  69. //bool is_avatar = objectp->isAvatar();
  70. if(is_root && is_prim)
  71. {
  72. LLSD element;
  73. element["id"] = objectp->getID();
  74. LLSD& check_column = element["columns"][LIST_CHECKED];
  75. check_column["column"] = "checked";
  76. check_column["type"] = "checkbox";
  77. check_column["value"] = true;
  78. LLSD& type_column = element["columns"][LIST_TYPE];
  79. type_column["column"] = "type";
  80. type_column["type"] = "icon";
  81. type_column["value"] = "inv_item_object.tga";
  82. LLSD& name_column = element["columns"][LIST_NAME];
  83. name_column["column"] = "name";
  84. /*if(is_attachment)
  85. name_column["value"] = nodep->mName + " (worn on " + utf8str_tolower(objectp->getAttachmentPointName()) + ")";
  86. else*/
  87. name_column["value"] = "Object";
  88. LLSD& avatarid_column = element["columns"][LIST_AVATARID];
  89. avatarid_column["column"] = "avatarid";
  90. if(is_attachment)
  91. avatarid_column["value"] = parentp->getID();
  92. else
  93. avatarid_column["value"] = LLUUID::null;
  94. LLExportable* exportable = new LLExportable(objectp, "Object", mPrimNameMap);
  95. mExportables[objectp->getID()] = exportable->asLLSD();
  96. list->addElement(element, ADD_BOTTOM);
  97. addToPrimList(objectp);
  98. }//Do we really want avatars in the region exporter?
  99. /*
  100. else if(is_avatar)
  101. {
  102. if(!avatars[objectp])
  103. {
  104. avatars[objectp] = true;
  105. }
  106. }
  107. */
  108. }
  109. }
  110. U32 localid = objectp->getLocalID();
  111. std::string name = "Object";
  112. mPrimNameMap[localid] = name;
  113. //Let's get names...
  114. LLViewerObject::child_list_t child_list = objectp->getChildren();
  115. for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
  116. {
  117. LLViewerObject* childp = *i;
  118. LLViewerObject::child_list_t select_list = childp->getChildren();
  119. LLViewerObject::child_list_t::iterator select_iter;
  120. int block_counter;
  121. gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
  122. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  123. gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  124. gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
  125. gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
  126. gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID());
  127. block_counter = 0;
  128. for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter)
  129. {
  130. block_counter++;
  131. if(block_counter >= 254)
  132. {
  133. // start a new message
  134. gMessageSystem->sendReliable(childp->getRegion()->getHost());
  135. gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
  136. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  137. gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  138. gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
  139. }
  140. gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
  141. gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID());
  142. }
  143. gMessageSystem->sendReliable(childp->getRegion()->getHost());
  144. gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
  145. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  146. gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  147. gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
  148. gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
  149. gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID());
  150. block_counter = 0;
  151. for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter)
  152. {
  153. block_counter++;
  154. if(block_counter >= 254)
  155. {
  156. // start a new message
  157. gMessageSystem->sendReliable(childp->getRegion()->getHost());
  158. gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
  159. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  160. gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  161. gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
  162. }
  163. gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
  164. gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID());
  165. }
  166. gMessageSystem->sendReliable(childp->getRegion()->getHost());
  167. }
  168. }
  169. //Do we really want avatars in the region exporter?
  170. /*std::map<LLViewerObject*, bool>::iterator avatar_iter = avatars.begin();
  171. std::map<LLViewerObject*, bool>::iterator avatars_end = avatars.end();
  172. for( ; avatar_iter != avatars_end; avatar_iter++)
  173. {
  174. LLViewerObject* avatar = (*avatar_iter).first;
  175. addAvatarStuff((LLVOAvatar*)avatar);
  176. }*/
  177. updateNamesProgress();
  178. childSetAction("select_all_btn", onClickSelectAll, this);
  179. childSetEnabled("select_objects_btn", FALSE);
  180. childSetEnabled("select_wearables_btn", FALSE);
  181. childSetAction("save_as_btn", onClickSaveAs, this);
  182. childSetEnabled("make_copy_btn", FALSE);
  183. return TRUE;
  184. }
  185. //static
  186. void LLFloaterExportRegion::onClickSelectAll(void* user_data)
  187. {
  188. LLFloaterExport* floater = (LLFloaterExport*)user_data;
  189. LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
  190. std::vector<LLScrollListItem*> items = list->getAllData();
  191. std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
  192. std::vector<LLScrollListItem*>::iterator items_end = items.end();
  193. if(items.size())
  194. {
  195. bool new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
  196. for( ; item_iter != items_end; ++item_iter)
  197. {
  198. LLScrollListItem* item = (*item_iter);
  199. item->getColumn(LIST_CHECKED)->setValue(new_value);
  200. }
  201. }
  202. }
  203. LLSD LLFloaterExportRegion::getLLSD()
  204. {
  205. LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
  206. std::vector<LLScrollListItem*> items = list->getAllData();
  207. LLSD sd;
  208. std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
  209. std::vector<LLScrollListItem*>::iterator items_end = items.end();
  210. for( ; item_iter != items_end; ++item_iter)
  211. {
  212. LLScrollListItem* item = (*item_iter);
  213. if(item->getColumn(LIST_CHECKED)->getValue())
  214. {
  215. LLSD item_sd = mExportables[item->getUUID()];
  216. LLSD::map_iterator map_iter = item_sd.beginMap();
  217. LLSD::map_iterator map_end = item_sd.endMap();
  218. for( ; map_iter != map_end; ++map_iter)
  219. {
  220. std::string key((*map_iter).first);
  221. LLSD data = (*map_iter).second;
  222. // copy it...
  223. sd[key] = data;
  224. }
  225. }
  226. }
  227. return sd;
  228. }
  229. //static
  230. void LLFloaterExportRegion::onClickSaveAs(void* user_data)
  231. {
  232. LLFloaterExport* floater = (LLFloaterExport*)user_data;
  233. LLSD sd = floater->getLLSD();
  234. if(sd.size())
  235. {
  236. std::string default_filename = "untitled";
  237. // set correct names within llsd
  238. LLSD::map_iterator map_iter = sd.beginMap();
  239. LLSD::map_iterator map_end = sd.endMap();
  240. for( ; map_iter != map_end; ++map_iter)
  241. {
  242. std::istringstream keystr((*map_iter).first);
  243. U32 key;
  244. keystr >> key;
  245. LLSD item = (*map_iter).second;
  246. if(item["type"].asString() == "prim")
  247. {
  248. std::string name = floater->mPrimNameMap[key];
  249. item["name"] = name;
  250. // I don't understand C++ :(
  251. sd[(*map_iter).first] = item;
  252. }
  253. }
  254. // count the number of selected items
  255. LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
  256. std::vector<LLScrollListItem*> items = list->getAllData();
  257. int item_count = 0;
  258. LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID();
  259. bool all_same_avatarid = true;
  260. std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
  261. std::vector<LLScrollListItem*>::iterator items_end = items.end();
  262. for( ; item_iter != items_end; ++item_iter)
  263. {
  264. LLScrollListItem* item = (*item_iter);
  265. if(item->getColumn(LIST_CHECKED)->getValue())
  266. {
  267. item_count++;
  268. if(item->getColumn(LIST_AVATARID)->getValue().asUUID() != avatarid)
  269. {
  270. all_same_avatarid = false;
  271. }
  272. }
  273. }
  274. if(item_count == 1)
  275. {
  276. // Exporting one item? Use its name for the filename.
  277. // But make sure it's a root!
  278. LLSD target = (*(sd.beginMap())).second;
  279. if(target.has("parent"))
  280. {
  281. std::string parentid = target["parent"].asString();
  282. target = sd[parentid];
  283. }
  284. if(target.has("name"))
  285. {
  286. if(target["name"].asString().length() > 0)
  287. {
  288. default_filename = target["name"].asString();
  289. }
  290. }
  291. }
  292. else
  293. {
  294. // Multiple items?
  295. // If they're all part of the same avatar, use the avatar's name as filename.
  296. if(all_same_avatarid)
  297. {
  298. std::string fullname;
  299. if(gCacheName->getFullName(avatarid, fullname))
  300. {
  301. default_filename = fullname;
  302. }
  303. }
  304. }
  305. LLFilePicker& file_picker = LLFilePicker::instance();
  306. if(file_picker.getSaveFile( LLFilePicker::FFSAVE_XML, LLDir::getScrubbedFileName(default_filename + ".xml")))
  307. {
  308. std::string file_name = file_picker.getFirstFile();
  309. llofstream export_file(file_name);
  310. LLSDSerialize::toPrettyXML(sd, export_file);
  311. export_file.close();
  312. std::string msg = "Saved ";
  313. msg.append(file_name);
  314. LLChat chat(msg);
  315. LLFloaterChat::addChat(chat);
  316. }
  317. }
  318. else
  319. {
  320. std::string msg = "No exportable items selected";
  321. LLChat chat(msg);
  322. LLFloaterChat::addChat(chat);
  323. return;
  324. }
  325. floater->close();
  326. }
  327. void LLFloaterExportRegion::addToPrimList(LLViewerObject* object)
  328. {
  329. mPrimList.push_back(object->getLocalID());
  330. LLViewerObject::child_list_t child_list = object->getChildren();
  331. for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
  332. {
  333. LLViewerObject* child = *i;
  334. if(child->getPCode() < LL_PCODE_APP)
  335. {
  336. mPrimList.push_back(child->getLocalID());
  337. }
  338. }
  339. }
  340. void LLFloaterExportRegion::updateNamesProgress()
  341. {
  342. childSetText("names_progress_text", llformat("Names retrieved: %d of %d", mPrimNameMap.size(), mPrimList.size()));
  343. }
  344. void LLFloaterExportRegion::receivePrimName(LLViewerObject* object, std::string name)
  345. {
  346. LLUUID fullid = object->getID();
  347. U32 localid = object->getLocalID();
  348. if(std::find(mPrimList.begin(), mPrimList.end(), localid) != mPrimList.end())
  349. {
  350. mPrimNameMap[localid] = name;
  351. LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
  352. S32 item_index = list->getItemIndex(fullid);
  353. if(item_index != -1)
  354. {
  355. std::vector<LLScrollListItem*> items = list->getAllData();
  356. std::vector<LLScrollListItem*>::iterator iter = items.begin();
  357. std::vector<LLScrollListItem*>::iterator end = items.end();
  358. for( ; iter != end; ++iter)
  359. {
  360. if((*iter)->getUUID() == fullid)
  361. {
  362. (*iter)->getColumn(LIST_NAME)->setValue(name + " (worn on " + utf8str_tolower(object->getAttachmentPointName()) + ")");
  363. break;
  364. }
  365. }
  366. }
  367. updateNamesProgress();
  368. }
  369. }
  370. // static
  371. void LLFloaterExportRegion::receiveObjectProperties(LLUUID fullid, std::string name, std::string desc)
  372. {
  373. LLViewerObject* object = gObjectList.findObject(fullid);
  374. std::vector<LLFloaterExport*>::iterator iter = LLFloaterExport::instances.begin();
  375. std::vector<LLFloaterExport*>::iterator end = LLFloaterExport::instances.end();
  376. for( ; iter != end; ++iter)
  377. {
  378. (*iter)->receivePrimName(object, name);
  379. }
  380. }
  381. // </edit>