llpreviewnotecard.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:15k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llpreviewnotecard.cpp
  3.  * @brief Implementation of the notecard editor
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llpreviewnotecard.h"
  34. #include "llinventory.h"
  35. #include "llagent.h"
  36. #include "llassetuploadresponders.h"
  37. #include "llviewerwindow.h"
  38. #include "llbutton.h"
  39. #include "llfloaterreg.h"
  40. #include "llinventorymodel.h"
  41. #include "lllineeditor.h"
  42. #include "llnotificationsutil.h"
  43. #include "llresmgr.h"
  44. #include "roles_constants.h"
  45. #include "llscrollbar.h"
  46. #include "llselectmgr.h"
  47. #include "llviewertexteditor.h"
  48. #include "llvfile.h"
  49. #include "llviewerinventory.h"
  50. #include "llviewerobject.h"
  51. #include "llviewerobjectlist.h"
  52. #include "llviewerregion.h"
  53. #include "lldir.h"
  54. #include "llviewerstats.h"
  55. #include "llviewercontrol.h" // gSavedSettings
  56. #include "llappviewer.h" // app_abort_quit()
  57. #include "lllineeditor.h"
  58. #include "lluictrlfactory.h"
  59. ///----------------------------------------------------------------------------
  60. /// Class LLPreviewNotecard
  61. ///----------------------------------------------------------------------------
  62. // Default constructor
  63. LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id, 
  64. : LLPreview( key )
  65. {
  66. const LLInventoryItem *item = getItem();
  67. if (item)
  68. {
  69. mAssetID = item->getAssetUUID();
  70. }
  71. //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_notecard.xml", FALSE);
  72. }
  73. LLPreviewNotecard::~LLPreviewNotecard()
  74. {
  75. }
  76. BOOL LLPreviewNotecard::postBuild()
  77. {
  78. LLViewerTextEditor *ed = getChild<LLViewerTextEditor>("Notecard Editor");
  79. ed->setNotecardInfo(mItemUUID, mObjectID, getKey());
  80. ed->makePristine();
  81. childSetAction("Save", onClickSave, this);
  82. childSetVisible("lock", FALSE);
  83. const LLInventoryItem* item = getItem();
  84. childSetCommitCallback("desc", LLPreview::onText, this);
  85. if (item)
  86. childSetText("desc", item->getDescription());
  87. childSetPrevalidate("desc", &LLTextValidate::validateASCIIPrintableNoPipe);
  88. return LLPreview::postBuild();
  89. }
  90. bool LLPreviewNotecard::saveItem()
  91. {
  92. LLInventoryItem* item = gInventory.getItem(mItemUUID);
  93. return saveIfNeeded(item);
  94. }
  95. void LLPreviewNotecard::setEnabled( BOOL enabled )
  96. {
  97. LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
  98. childSetEnabled("Notecard Editor", enabled);
  99. childSetVisible("lock", !enabled);
  100. childSetEnabled("desc", enabled);
  101. childSetEnabled("Save", enabled && editor && (!editor->isPristine()));
  102. }
  103. void LLPreviewNotecard::draw()
  104. {
  105. LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
  106. BOOL changed = !editor->isPristine();
  107. childSetEnabled("Save", changed && getEnabled());
  108. LLPreview::draw();
  109. }
  110. // virtual
  111. BOOL LLPreviewNotecard::handleKeyHere(KEY key, MASK mask)
  112. {
  113. if(('S' == key) && (MASK_CONTROL == (mask & MASK_CONTROL)))
  114. {
  115. saveIfNeeded();
  116. return TRUE;
  117. }
  118. return LLPreview::handleKeyHere(key, mask);
  119. }
  120. // virtual
  121. BOOL LLPreviewNotecard::canClose()
  122. {
  123. LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
  124. if(mForceClose || editor->isPristine())
  125. {
  126. return TRUE;
  127. }
  128. else
  129. {
  130. // Bring up view-modal dialog: Save changes? Yes, No, Cancel
  131. LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleSaveChangesDialog,this, _1, _2));
  132.   
  133. return FALSE;
  134. }
  135. }
  136. const LLInventoryItem* LLPreviewNotecard::getDragItem()
  137. {
  138. LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
  139. if(editor)
  140. {
  141. return editor->getDragItem();
  142. }
  143. return NULL;
  144. }
  145. bool LLPreviewNotecard::hasEmbeddedInventory()
  146. {
  147. LLViewerTextEditor* editor = NULL;
  148. editor = getChild<LLViewerTextEditor>("Notecard Editor");
  149. if (!editor) return false;
  150. return editor->hasEmbeddedInventory();
  151. }
  152. void LLPreviewNotecard::refreshFromInventory(const LLUUID& new_item_id)
  153. {
  154. if (new_item_id.notNull())
  155. {
  156. mItemUUID = new_item_id;
  157. setKey(LLSD(new_item_id));
  158. }
  159. lldebugs << "LLPreviewNotecard::refreshFromInventory()" << llendl;
  160. loadAsset();
  161. }
  162. void LLPreviewNotecard::loadAsset()
  163. {
  164. // request the asset.
  165. const LLInventoryItem* item = getItem();
  166. LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
  167. if (!editor)
  168. return;
  169. if(item)
  170. {
  171. if (gAgent.allowOperation(PERM_COPY, item->getPermissions(),
  172. GP_OBJECT_MANIPULATE)
  173. || gAgent.isGodlike())
  174. {
  175. mAssetID = item->getAssetUUID();
  176. if(mAssetID.isNull())
  177. {
  178. editor->setText(LLStringUtil::null);
  179. editor->makePristine();
  180. editor->setEnabled(TRUE);
  181. mAssetStatus = PREVIEW_ASSET_LOADED;
  182. }
  183. else
  184. {
  185. LLHost source_sim = LLHost::invalid;
  186. if (mObjectUUID.notNull())
  187. {
  188. LLViewerObject *objectp = gObjectList.findObject(mObjectUUID);
  189. if (objectp && objectp->getRegion())
  190. {
  191. source_sim = objectp->getRegion()->getHost();
  192. }
  193. else
  194. {
  195. // The object that we're trying to look at disappeared, bail.
  196. llwarns << "Can't find object " << mObjectUUID << " associated with notecard." << llendl;
  197. mAssetID.setNull();
  198. editor->setText(getString("no_object"));
  199. editor->makePristine();
  200. editor->setEnabled(FALSE);
  201. mAssetStatus = PREVIEW_ASSET_LOADED;
  202. return;
  203. }
  204. }
  205. gAssetStorage->getInvItemAsset(source_sim,
  206. gAgent.getID(),
  207. gAgent.getSessionID(),
  208. item->getPermissions().getOwner(),
  209. mObjectUUID,
  210. item->getUUID(),
  211. item->getAssetUUID(),
  212. item->getType(),
  213. &onLoadComplete,
  214. (void*)new LLUUID(mItemUUID),
  215. TRUE);
  216. mAssetStatus = PREVIEW_ASSET_LOADING;
  217. }
  218. }
  219. else
  220. {
  221. mAssetID.setNull();
  222. editor->setText(getString("not_allowed"));
  223. editor->makePristine();
  224. editor->setEnabled(FALSE);
  225. mAssetStatus = PREVIEW_ASSET_LOADED;
  226. }
  227. if(!gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
  228. GP_OBJECT_MANIPULATE))
  229. {
  230. editor->setEnabled(FALSE);
  231. childSetVisible("lock", TRUE);
  232. }
  233. }
  234. else
  235. {
  236. editor->setText(LLStringUtil::null);
  237. editor->makePristine();
  238. editor->setEnabled(TRUE);
  239. // Don't set asset status here; we may not have set the item id yet
  240. // (e.g. when this gets called initially)
  241. //mAssetStatus = PREVIEW_ASSET_LOADED;
  242. }
  243. }
  244. // static
  245. void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
  246.    const LLUUID& asset_uuid,
  247.    LLAssetType::EType type,
  248.    void* user_data, S32 status, LLExtStat ext_status)
  249. {
  250. llinfos << "LLPreviewNotecard::onLoadComplete()" << llendl;
  251. LLUUID* item_id = (LLUUID*)user_data;
  252. LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(*item_id));
  253. if( preview )
  254. {
  255. if(0 == status)
  256. {
  257. LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
  258. S32 file_length = file.getSize();
  259. std::vector<char> buffer(file_length+1);
  260. file.read((U8*)&buffer[0], file_length);
  261. // put a EOS at the end
  262. buffer[file_length] = 0;
  263. LLViewerTextEditor* previewEditor = preview->getChild<LLViewerTextEditor>("Notecard Editor");
  264. if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) )
  265. {
  266. if( !previewEditor->importBuffer( &buffer[0], file_length+1 ) )
  267. {
  268. llwarns << "Problem importing notecard" << llendl;
  269. }
  270. }
  271. else
  272. {
  273. // Version 0 (just text, doesn't include version number)
  274. previewEditor->setText(LLStringExplicit(&buffer[0]));
  275. }
  276. previewEditor->makePristine();
  277. const LLInventoryItem* item = preview->getItem();
  278. BOOL modifiable = item && gAgent.allowOperation(PERM_MODIFY,
  279. item->getPermissions(), GP_OBJECT_MANIPULATE);
  280. preview->setEnabled(modifiable);
  281. preview->mAssetStatus = PREVIEW_ASSET_LOADED;
  282. }
  283. else
  284. {
  285. LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
  286. if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
  287. LL_ERR_FILE_EMPTY == status)
  288. {
  289. LLNotificationsUtil::add("NotecardMissing");
  290. }
  291. else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
  292. {
  293. LLNotificationsUtil::add("NotecardNoPermissions");
  294. }
  295. else
  296. {
  297. LLNotificationsUtil::add("UnableToLoadNotecard");
  298. }
  299. llwarns << "Problem loading notecard: " << status << llendl;
  300. preview->mAssetStatus = PREVIEW_ASSET_ERROR;
  301. }
  302. }
  303. delete item_id;
  304. }
  305. // static
  306. void LLPreviewNotecard::onClickSave(void* user_data)
  307. {
  308. //llinfos << "LLPreviewNotecard::onBtnSave()" << llendl;
  309. LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data;
  310. if(preview)
  311. {
  312. preview->saveIfNeeded();
  313. }
  314. }
  315. struct LLSaveNotecardInfo
  316. {
  317. LLPreviewNotecard* mSelf;
  318. LLUUID mItemUUID;
  319. LLUUID mObjectUUID;
  320. LLTransactionID mTransactionID;
  321. LLPointer<LLInventoryItem> mCopyItem;
  322. LLSaveNotecardInfo(LLPreviewNotecard* self, const LLUUID& item_id, const LLUUID& object_id,
  323.    const LLTransactionID& transaction_id, LLInventoryItem* copyitem) :
  324. mSelf(self), mItemUUID(item_id), mObjectUUID(object_id), mTransactionID(transaction_id), mCopyItem(copyitem)
  325. {
  326. }
  327. };
  328. bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
  329. {
  330. if(!gAssetStorage)
  331. {
  332. llwarns << "Not connected to an asset storage system." << llendl;
  333. return false;
  334. }
  335. LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
  336. if(!editor->isPristine())
  337. {
  338. // We need to update the asset information
  339. LLTransactionID tid;
  340. LLAssetID asset_id;
  341. tid.generate();
  342. asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
  343. LLVFile file(gVFS, asset_id, LLAssetType::AT_NOTECARD, LLVFile::APPEND);
  344. std::string buffer;
  345. if (!editor->exportBuffer(buffer))
  346. {
  347. return false;
  348. }
  349. editor->makePristine();
  350. S32 size = buffer.length() + 1;
  351. file.setMaxSize(size);
  352. file.write((U8*)buffer.c_str(), size);
  353. const LLInventoryItem* item = getItem();
  354. // save it out to database
  355. if (item)
  356. {
  357. std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory");
  358. std::string task_url = gAgent.getRegion()->getCapability("UpdateNotecardTaskInventory");
  359. if (mObjectUUID.isNull() && !agent_url.empty())
  360. {
  361. // Saving into agent inventory
  362. mAssetStatus = PREVIEW_ASSET_LOADING;
  363. setEnabled(FALSE);
  364. LLSD body;
  365. body["item_id"] = mItemUUID;
  366. llinfos << "Saving notecard " << mItemUUID
  367. << " into agent inventory via " << agent_url << llendl;
  368. LLHTTPClient::post(agent_url, body,
  369. new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD));
  370. }
  371. else if (!mObjectUUID.isNull() && !task_url.empty())
  372. {
  373. // Saving into task inventory
  374. mAssetStatus = PREVIEW_ASSET_LOADING;
  375. setEnabled(FALSE);
  376. LLSD body;
  377. body["task_id"] = mObjectUUID;
  378. body["item_id"] = mItemUUID;
  379. llinfos << "Saving notecard " << mItemUUID << " into task "
  380. << mObjectUUID << " via " << task_url << llendl;
  381. LLHTTPClient::post(task_url, body,
  382. new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD));
  383. }
  384. else if (gAssetStorage)
  385. {
  386. LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID,
  387. tid, copyitem);
  388. gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD,
  389. &onSaveComplete,
  390. (void*)info,
  391. FALSE);
  392. }
  393. }
  394. }
  395. return true;
  396. }
  397. // static
  398. void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
  399. {
  400. LLSaveNotecardInfo* info = (LLSaveNotecardInfo*)user_data;
  401. if(info && (0 == status))
  402. {
  403. if(info->mObjectUUID.isNull())
  404. {
  405. LLViewerInventoryItem* item;
  406. item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID);
  407. if(item)
  408. {
  409. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  410. new_item->setAssetUUID(asset_uuid);
  411. new_item->setTransactionID(info->mTransactionID);
  412. new_item->updateServer(FALSE);
  413. gInventory.updateItem(new_item);
  414. gInventory.notifyObservers();
  415. }
  416. else
  417. {
  418. llwarns << "Inventory item for script " << info->mItemUUID
  419. << " is no longer in agent inventory." << llendl;
  420. }
  421. }
  422. else
  423. {
  424. LLViewerObject* object = gObjectList.findObject(info->mObjectUUID);
  425. LLViewerInventoryItem* item = NULL;
  426. if(object)
  427. {
  428. item = (LLViewerInventoryItem*)object->getInventoryObject(info->mItemUUID);
  429. }
  430. if(object && item)
  431. {
  432. item->setAssetUUID(asset_uuid);
  433. item->setTransactionID(info->mTransactionID);
  434. object->updateInventory(item, TASK_INVENTORY_ITEM_KEY, false);
  435. dialog_refresh_all();
  436. }
  437. else
  438. {
  439. LLNotificationsUtil::add("SaveNotecardFailObjectNotFound");
  440. }
  441. }
  442. // Perform item copy to inventory
  443. if (info->mCopyItem.notNull())
  444. {
  445. LLViewerTextEditor* editor = info->mSelf->getChild<LLViewerTextEditor>("Notecard Editor");
  446. if (editor)
  447. {
  448. editor->copyInventory(info->mCopyItem);
  449. }
  450. }
  451. // Find our window and close it if requested.
  452. LLPreviewNotecard* previewp = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", info->mItemUUID);
  453. if (previewp && previewp->mCloseAfterSave)
  454. {
  455. previewp->closeFloater();
  456. }
  457. }
  458. else
  459. {
  460. llwarns << "Problem saving notecard: " << status << llendl;
  461. LLSD args;
  462. args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
  463. LLNotificationsUtil::add("SaveNotecardFailReason", args);
  464. }
  465. std::string uuid_string;
  466. asset_uuid.toString(uuid_string);
  467. std::string filename;
  468. filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string) + ".tmp";
  469. LLFile::remove(filename);
  470. delete info;
  471. }
  472. bool LLPreviewNotecard::handleSaveChangesDialog(const LLSD& notification, const LLSD& response)
  473. {
  474. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  475. switch(option)
  476. {
  477. case 0:  // "Yes"
  478. mCloseAfterSave = TRUE;
  479. LLPreviewNotecard::onClickSave((void*)this);
  480. break;
  481. case 1:  // "No"
  482. mForceClose = TRUE;
  483. closeFloater();
  484. break;
  485. case 2: // "Cancel"
  486. default:
  487. // If we were quitting, we didn't really mean it.
  488. LLAppViewer::instance()->abortQuit();
  489. break;
  490. }
  491. return false;
  492. }
  493. // EOF