llpanelpermissions.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. /**
  2. * @file llpanelpermissions.cpp
  3. * @brief LLPanelPermissions class implementation
  4. * This class represents the panel in the build view for
  5. * viewing/editing object names, owners, permissions, etc.
  6. *
  7. * $LicenseInfo:firstyear=2002&license=viewergpl$
  8. *
  9. * Copyright (c) 2002-2009, Linden Research, Inc.
  10. *
  11. * Second Life Viewer Source Code
  12. * The source code in this file ("Source Code") is provided by Linden Lab
  13. * to you under the terms of the GNU General Public License, version 2.0
  14. * ("GPL"), unless you have obtained a separate licensing agreement
  15. * ("Other License"), formally executed by you and Linden Lab. Terms of
  16. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18. *
  19. * There are special exceptions to the terms and conditions of the GPL as
  20. * it is applied to this Source Code. View the full text of the exception
  21. * in the file doc/FLOSS-exception.txt in this software distribution, or
  22. * online at
  23. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24. *
  25. * By copying, modifying or distributing this software, you acknowledge
  26. * that you have read and understood your obligations described above,
  27. * and agree to abide by those obligations.
  28. *
  29. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31. * COMPLETENESS OR PERFORMANCE.
  32. * $/LicenseInfo$
  33. */
  34. #include "llviewerprecompiledheaders.h"
  35. #include "llpanelpermissions.h"
  36. #include "llbutton.h"
  37. #include "llcategory.h"
  38. #include "llcheckboxctrl.h"
  39. #include "llcombobox.h"
  40. #include "lliconctrl.h"
  41. #include "lllineeditor.h"
  42. #include "llnamebox.h"
  43. #include "llpermissions.h"
  44. #include "llradiogroup.h"
  45. #include "lltextbox.h"
  46. #include "lluictrlfactory.h"
  47. #include "roles_constants.h"
  48. #include "llagent.h"
  49. #include "llfloateravatarinfo.h"
  50. #include "llfloatergroupinfo.h"
  51. #include "llfloatergroups.h"
  52. #include "llinventorymodel.h"
  53. //MK
  54. #include "mkrlinterface.h"
  55. //mk
  56. #include "hbobjectbackup.h" // For HBObjectBackup::validateAssetPerms()
  57. #include "llviewercontrol.h"
  58. ///----------------------------------------------------------------------------
  59. /// Class llpanelpermissions
  60. ///----------------------------------------------------------------------------
  61. // Default constructor
  62. LLPanelPermissions::LLPanelPermissions(const std::string& title)
  63. : LLPanel(title)
  64. {
  65. setMouseOpaque(false);
  66. }
  67. //virtual
  68. bool LLPanelPermissions::postBuild()
  69. {
  70. // Object name
  71. mTextObjectName = getChild<LLTextBox>("Name:");
  72. mEditorObjectName = getChild<LLLineEditor>("Object Name");
  73. mEditorObjectName->setCommitCallback(onCommitName);
  74. mEditorObjectName->setCallbackUserData(this);
  75. mEditorObjectName->setPrevalidate(LLLineEditor::prevalidatePrintableNotPipe);
  76. // Object description
  77. mTextObjectDesc = getChild<LLTextBox>("Description:");
  78. mEditorObjectDesc = getChild<LLLineEditor>("Object Description");
  79. mEditorObjectDesc->setCommitCallback(onCommitDesc);
  80. mEditorObjectDesc->setCallbackUserData(this);
  81. mEditorObjectDesc->setPrevalidate(LLLineEditor::prevalidatePrintableNotPipe);
  82. // Object creator
  83. mTextCreatorLabel = getChild<LLTextBox>("Creator:");
  84. mTextCreatorName = getChild<LLTextBox>("Creator Name");
  85. mButtonCreatorProfile = getChild<LLButton>("button creator profile");
  86. mButtonCreatorProfile->setClickedCallback(onClickCreator, this);
  87. // Object owner
  88. mTextOwnerLabel = getChild<LLTextBox>("Owner:");
  89. mTextOwnerName = getChild<LLTextBox>("Owner Name");
  90. mButtonOwnerProfile = getChild<LLButton>("button owner profile");
  91. mButtonOwnerProfile->setClickedCallback(onClickOwner, this);
  92. // Object group
  93. mTextGroupName = getChild<LLTextBox>("Group:");
  94. LLTextBox* group_name = getChild<LLTextBox>("Group Name Proxy");
  95. mNameBoxGroupName = new LLNameBox("Group Name", group_name->getRect());
  96. addChild(mNameBoxGroupName);
  97. mButtonSetGroup = getChild<LLButton>("button set group");
  98. mButtonSetGroup->setClickedCallback(onClickGroup, this);
  99. // Permissions
  100. mTextPermissions = getChild<LLTextBox>("Permissions:");
  101. mTextPermissionsModify = getChild<LLTextBox>("perm_modify");
  102. mCheckShareWithGroup = getChild<LLCheckBoxCtrl>("share_with_group");
  103. mCheckShareWithGroup->setCommitCallback(onCommitGroupShare);
  104. mCheckShareWithGroup->setCallbackUserData(this);
  105. mButtonDeed = getChild<LLButton>("button deed");
  106. mButtonDeed->setClickedCallback(onClickDeedToGroup, this);
  107. mCheckAllowEveryoneExport = getChild<LLCheckBoxCtrl>("allow_export");
  108. mCheckAllowEveryoneExport->setCommitCallback(onCommitEveryoneExport);
  109. mCheckAllowEveryoneExport->setCallbackUserData(this);
  110. mCheckAllowEveryoneMove = getChild<LLCheckBoxCtrl>("everyone_move");
  111. mCheckAllowEveryoneMove->setCommitCallback(onCommitEveryoneMove);
  112. mCheckAllowEveryoneMove->setCallbackUserData(this);
  113. mCheckAllowEveryoneCopy = getChild<LLCheckBoxCtrl>("everyone_copy");
  114. mCheckAllowEveryoneCopy->setCommitCallback(onCommitEveryoneCopy);
  115. mCheckAllowEveryoneCopy->setCallbackUserData(this);
  116. mCheckShowInSearch = getChild<LLCheckBoxCtrl>("search_check");
  117. mCheckShowInSearch->setCommitCallback(onCommitIncludeInSearch);
  118. mCheckShowInSearch->setCallbackUserData(this);
  119. mCheckForSale = getChild<LLCheckBoxCtrl>("for_sale");
  120. mCheckForSale->setCommitCallback(onCommitSaleInfo);
  121. mCheckForSale->setCallbackUserData(this);
  122. mTextCost = getChild<LLTextBox>("Cost");
  123. mEditorCost = getChild<LLLineEditor>("Edit Cost");
  124. mEditorCost->setCommitCallback(onCommitSaleInfo);
  125. mEditorCost->setCallbackUserData(this);
  126. mEditorCost->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
  127. mRadioSaleType = getChild<LLRadioGroup>("sale type");
  128. mRadioSaleType->setCommitCallback(onCommitSaleType);
  129. mRadioSaleType->setCallbackUserData(this);
  130. mTextNextOwnerCan = getChild<LLTextBox>("next_owner_can");
  131. mCheckNextCanModify = getChild<LLCheckBoxCtrl>("next_can_modify");
  132. mCheckNextCanModify->setCommitCallback(onCommitNextOwnerModify);
  133. mCheckNextCanModify->setCallbackUserData(this);
  134. mCheckNextCanCopy = getChild<LLCheckBoxCtrl>("next_can_copy");
  135. mCheckNextCanCopy->setCommitCallback(onCommitNextOwnerCopy);
  136. mCheckNextCanCopy->setCallbackUserData(this);
  137. mCheckNextCanTransfer = getChild<LLCheckBoxCtrl>("next_can_transfer");
  138. mCheckNextCanTransfer->setCommitCallback(onCommitNextOwnerTransfer);
  139. mCheckNextCanTransfer->setCallbackUserData(this);
  140. mTextClickAction = getChild<LLTextBox>("label click action");
  141. mComboClickAction = getChild<LLComboBox>("clickaction");
  142. mComboClickAction->setCommitCallback(onCommitClickAction);
  143. mComboClickAction->setCallbackUserData(this);
  144. mIconNavMeshInfo = getChild<LLIconCtrl>("navmeshicon");
  145. mTextNavMeshInfo = getChild<LLTextBox>("navmeshinfo");
  146. mTextDebugPermB = getChild<LLTextBox>("B:");
  147. mTextDebugPermO = getChild<LLTextBox>("O:");
  148. mTextDebugPermG = getChild<LLTextBox>("G:");
  149. mTextDebugPermE = getChild<LLTextBox>("E:");
  150. mTextDebugPermN = getChild<LLTextBox>("N:");
  151. mTextDebugPermF = getChild<LLTextBox>("F:");
  152. mCostTotal = getString("Cost Total");
  153. mCostDefault = getString("Cost Default");
  154. mCostPerUnit = getString("Cost Per Unit");
  155. mCostMixed = getString("Cost Mixed");
  156. mSaleMixed = getString("Sale Mixed");
  157. return true;
  158. }
  159. //virtual
  160. void LLPanelPermissions::refresh()
  161. {
  162. // Static variables, to prevent calling getString() on each refresh()
  163. static std::string MODIFY_INFO_STRINGS[] =
  164. {
  165. getString("text modify info 1"),
  166. getString("text modify info 2"),
  167. getString("text modify info 3"),
  168. getString("text modify info 4"),
  169. getString("text modify info 5"),
  170. getString("text modify info 6"),
  171. getString("text modify warning")
  172. };
  173. static std::string text_deed = getString("text deed");
  174. static std::string text_deed_continued = getString("text deed continued");
  175. static LLCachedControl<bool> warn_deed_object(gSavedSettings,
  176. "WarnDeedObject");
  177. std::string deed_text = warn_deed_object ? text_deed_continued : text_deed;
  178. mButtonDeed->setLabelSelected(deed_text);
  179. mButtonDeed->setLabelUnselected(deed_text);
  180. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  181. LLSelectNode* nodep = selection->getFirstRootNode();
  182. S32 object_count = selection->getRootObjectCount();
  183. bool root_selected = true;
  184. if (!nodep || !object_count)
  185. {
  186. nodep = selection->getFirstNode();
  187. object_count = selection->getObjectCount();
  188. root_selected = false;
  189. }
  190. LLViewerObject* objectp = NULL;
  191. if (nodep) objectp = nodep->getObject();
  192. if (!nodep || !objectp)
  193. {
  194. // ...nothing selected
  195. mTextObjectName->setEnabled(false);
  196. mEditorObjectName->setText(LLStringUtil::null);
  197. mEditorObjectName->setEnabled(false);
  198. mTextObjectDesc->setEnabled(false);
  199. mEditorObjectDesc->setText(LLStringUtil::null);
  200. mEditorObjectDesc->setEnabled(false);
  201. mTextCreatorLabel->setEnabled(false);
  202. mTextCreatorName->setText(LLStringUtil::null);
  203. mTextCreatorName->setEnabled(false);
  204. mButtonCreatorProfile->setEnabled(false);
  205. mTextOwnerLabel->setEnabled(false);
  206. mTextOwnerName->setText(LLStringUtil::null);
  207. mTextOwnerName->setEnabled(false);
  208. mButtonOwnerProfile->setEnabled(false);
  209. mTextGroupName->setEnabled(false);
  210. mNameBoxGroupName->setText(LLStringUtil::null);
  211. mNameBoxGroupName->setEnabled(false);
  212. mButtonSetGroup->setEnabled(false);
  213. mTextPermissions->setEnabled(false);
  214. mTextPermissionsModify->setEnabled(false);
  215. mTextPermissionsModify->setText(LLStringUtil::null);
  216. mCheckShareWithGroup->set(false);
  217. mCheckShareWithGroup->setEnabled(false);
  218. mButtonDeed->setEnabled(false);
  219. mCheckAllowEveryoneExport->set(false);
  220. mCheckAllowEveryoneExport->setEnabled(false);
  221. mCheckAllowEveryoneMove->set(false);
  222. mCheckAllowEveryoneMove->setEnabled(false);
  223. mCheckAllowEveryoneCopy->set(false);
  224. mCheckAllowEveryoneCopy->setEnabled(false);
  225. // Next owner can:
  226. mTextNextOwnerCan->setEnabled(false);
  227. mCheckNextCanModify->set(false);
  228. mCheckNextCanModify->setEnabled(false);
  229. mCheckNextCanCopy->set(false);
  230. mCheckNextCanCopy->setEnabled(false);
  231. mCheckNextCanTransfer->set(false);
  232. mCheckNextCanTransfer->setEnabled(false);
  233. // path finding info
  234. mIconNavMeshInfo->setVisible(false);
  235. mTextNavMeshInfo->setVisible(false);
  236. // checkbox include in search
  237. mCheckShowInSearch->set(false);
  238. mCheckShowInSearch->setEnabled(false);
  239. // checkbox for sale
  240. mCheckForSale->set(false);
  241. mCheckForSale->setEnabled(false);
  242. mRadioSaleType->setSelectedIndex(-1);
  243. mRadioSaleType->setEnabled(false);
  244. mTextCost->setText(mCostDefault);
  245. mTextCost->setEnabled(false);
  246. mEditorCost->setText(LLStringUtil::null);
  247. mEditorCost->setEnabled(false);
  248. mTextClickAction->setEnabled(false);
  249. mComboClickAction->setEnabled(false);
  250. mComboClickAction->clear();
  251. mTextDebugPermB->setVisible(false);
  252. mTextDebugPermO->setVisible(false);
  253. mTextDebugPermG->setVisible(false);
  254. mTextDebugPermE->setVisible(false);
  255. mTextDebugPermN->setVisible(false);
  256. mTextDebugPermF->setVisible(false);
  257. return;
  258. }
  259. mTextPermissions->setEnabled(true);
  260. // figure out a few variables
  261. bool is_one_object = object_count == 1;
  262. // BUG: fails if a root and non-root are both single-selected.
  263. bool is_perm_modify = gSelectMgr.selectGetModify() ||
  264. (selection->getFirstRootNode() &&
  265. gSelectMgr.selectGetRootsModify());
  266. bool is_nonpermanent_enforced =
  267. gSelectMgr.selectGetNonPermanentEnforced() ||
  268. (selection->getFirstRootNode() &&
  269. gSelectMgr.selectGetRootsNonPermanentEnforced());
  270. S32 string_index = 0;
  271. if (!is_perm_modify)
  272. {
  273. string_index += 2;
  274. }
  275. else if (!is_nonpermanent_enforced)
  276. {
  277. string_index += 4;
  278. }
  279. if (!is_one_object)
  280. {
  281. ++string_index;
  282. }
  283. mTextPermissionsModify->setEnabled(true);
  284. mTextPermissionsModify->setText(MODIFY_INFO_STRINGS[string_index]);
  285. // Path finding attributes, if any.
  286. std::string pf_info = gSelectMgr.getPathFindingAttributeInfo(true);
  287. bool pf_info_enabled = !pf_info.empty();
  288. if (pf_info_enabled)
  289. {
  290. mTextNavMeshInfo->setText(pf_info);
  291. }
  292. mIconNavMeshInfo->setVisible(pf_info_enabled);
  293. mTextNavMeshInfo->setVisible(pf_info_enabled);
  294. // Update creator text field
  295. mTextCreatorLabel->setEnabled(true);
  296. std::string creator_name;
  297. bool creators_identical = gSelectMgr.selectGetCreator(mCreatorID,
  298. creator_name);
  299. mTextCreatorName->setText(creator_name);
  300. mTextCreatorName->setEnabled(true);
  301. mButtonCreatorProfile->setEnabled(creators_identical && mCreatorID.notNull());
  302. // Update owner text field
  303. mTextOwnerLabel->setEnabled(true);
  304. std::string owner_name;
  305. bool owners_identical = gSelectMgr.selectGetOwner(mOwnerID, owner_name);
  306. if (mOwnerID.isNull())
  307. {
  308. if (gSelectMgr.selectIsGroupOwned())
  309. {
  310. // Group owned already displayed by selectGetOwner
  311. }
  312. else
  313. {
  314. // Display last owner if public
  315. std::string last_owner_name;
  316. gSelectMgr.selectGetLastOwner(mLastOwnerID, last_owner_name);
  317. // It should never happen that the last owner is null and the owner
  318. // is null, but it seems to be a bug in the simulator right now. JC
  319. if (mLastOwnerID.notNull() && !last_owner_name.empty())
  320. {
  321. owner_name.append(", last ");
  322. owner_name.append(last_owner_name);
  323. }
  324. }
  325. }
  326. //MK
  327. if (gRLenabled &&
  328. (gRLInterface.mContainsShownames ||
  329. gRLInterface.mContainsShownametags))
  330. {
  331. owner_name = gRLInterface.getDummyName(owner_name);
  332. }
  333. //mk
  334. mTextOwnerName->setText(owner_name);
  335. mTextOwnerName->setEnabled(true);
  336. mButtonOwnerProfile->setEnabled(owners_identical &&
  337. (mOwnerID.notNull() ||
  338. gSelectMgr.selectIsGroupOwned()));
  339. // update group text field
  340. mTextGroupName->setEnabled(true);
  341. mNameBoxGroupName->setText(LLStringUtil::null);
  342. LLUUID group_id;
  343. bool groups_identical = gSelectMgr.selectGetGroup(group_id);
  344. if (groups_identical)
  345. {
  346. mNameBoxGroupName->setNameID(group_id, true);
  347. mNameBoxGroupName->setEnabled(true);
  348. }
  349. else
  350. {
  351. mNameBoxGroupName->setNameID(LLUUID::null, true);
  352. mNameBoxGroupName->refresh(LLUUID::null, LLStringUtil::null, true);
  353. mNameBoxGroupName->setEnabled(false);
  354. }
  355. mButtonSetGroup->setEnabled(root_selected && owners_identical &&
  356. mOwnerID == gAgentID &&
  357. is_nonpermanent_enforced);
  358. // figure out the contents of the name, description, & category
  359. mTextObjectName->setEnabled(true);
  360. mTextObjectDesc->setEnabled(true);
  361. const LLFocusableElement* keyboard_focus_view = gFocusMgr.getKeyboardFocus();
  362. if (is_one_object)
  363. {
  364. if (keyboard_focus_view != mEditorObjectName)
  365. {
  366. mEditorObjectName->setText(nodep->mName);
  367. }
  368. if (keyboard_focus_view != mEditorObjectDesc)
  369. {
  370. mEditorObjectDesc->setText(nodep->mDescription);
  371. }
  372. }
  373. else
  374. {
  375. mEditorObjectName->setText(LLStringUtil::null);
  376. mEditorObjectDesc->setText(LLStringUtil::null);
  377. }
  378. bool edit_name_desc = is_one_object && objectp->permModify() &&
  379. !objectp->isPermanentEnforced();
  380. mEditorObjectName->setEnabled(edit_name_desc);
  381. mEditorObjectDesc->setEnabled(edit_name_desc);
  382. S32 total_sale_price = 0;
  383. S32 individual_sale_price = 0;
  384. bool is_for_sale_mixed = false;
  385. bool is_sale_price_mixed = false;
  386. U32 num_for_sale = 0;
  387. gSelectMgr.selectGetAggregateSaleInfo(num_for_sale, is_for_sale_mixed,
  388. is_sale_price_mixed,
  389. total_sale_price,
  390. individual_sale_price);
  391. bool self_owned = gAgentID == mOwnerID;
  392. bool group_owned = gSelectMgr.selectIsGroupOwned();
  393. bool public_owned = mOwnerID.isNull() && !gSelectMgr.selectIsGroupOwned();
  394. bool can_transfer = gSelectMgr.selectGetRootsTransfer();
  395. bool can_copy = gSelectMgr.selectGetRootsCopy();
  396. if (!owners_identical)
  397. {
  398. mTextCost->setEnabled(false);
  399. mEditorCost->setText(LLStringUtil::null);
  400. mEditorCost->setEnabled(false);
  401. }
  402. // You own these objects.
  403. else if (self_owned ||
  404. (group_owned &&
  405. gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE)))
  406. {
  407. // If there are multiple items for sale then set text to PRICE PER UNIT
  408. if (num_for_sale > 1)
  409. {
  410. mTextCost->setText(mCostPerUnit);
  411. }
  412. else
  413. {
  414. mTextCost->setText(mCostDefault);
  415. }
  416. if (keyboard_focus_view != mEditorCost)
  417. {
  418. // If the sale price is mixed then set the cost to MIXED, otherwise
  419. // set to the actual cost.
  420. if (num_for_sale > 0 && is_for_sale_mixed)
  421. {
  422. mEditorCost->setText(mSaleMixed);
  423. }
  424. else if (num_for_sale > 0 && is_sale_price_mixed)
  425. {
  426. mEditorCost->setText(mCostMixed);
  427. }
  428. else
  429. {
  430. mEditorCost->setText(llformat("%d", individual_sale_price));
  431. }
  432. }
  433. // The edit fields are only enabled if you can sell this object
  434. // and the sale price is not mixed.
  435. bool enable_edit = num_for_sale && can_transfer ? !is_for_sale_mixed
  436. : false;
  437. mTextCost->setEnabled(enable_edit);
  438. mEditorCost->setEnabled(enable_edit);
  439. }
  440. // Someone, not you, owns these objects.
  441. else if (!public_owned)
  442. {
  443. mTextCost->setEnabled(false);
  444. mEditorCost->setEnabled(false);
  445. // Don't show a price if none of the items are for sale.
  446. if (num_for_sale)
  447. {
  448. mEditorCost->setText(llformat("%d", total_sale_price));
  449. }
  450. else
  451. {
  452. mEditorCost->setText(LLStringUtil::null);
  453. }
  454. // If multiple items are for sale, set text to TOTAL PRICE.
  455. if (num_for_sale > 1)
  456. {
  457. mTextCost->setText(mCostTotal);
  458. }
  459. else
  460. {
  461. mTextCost->setText(mCostDefault);
  462. }
  463. }
  464. // This is a public object.
  465. else
  466. {
  467. mTextCost->setText(mCostDefault);
  468. mTextCost->setEnabled(false);
  469. mEditorCost->setText(LLStringUtil::null);
  470. mEditorCost->setEnabled(false);
  471. }
  472. // Enable and disable the permissions checkboxes based on who owns the
  473. // object. * TODO: Creator permissions
  474. bool valid_base_perms = false;
  475. bool valid_owner_perms = false;
  476. bool valid_group_perms = false;
  477. bool valid_everyone_perms = false;
  478. bool valid_next_perms = false;
  479. U32 base_mask_on = 0;
  480. U32 base_mask_off = 0;
  481. U32 owner_mask_on = 0;
  482. U32 owner_mask_off = 0;
  483. U32 group_mask_on = 0;
  484. U32 group_mask_off = 0;
  485. U32 everyone_mask_on = 0;
  486. U32 everyone_mask_off = 0;
  487. U32 next_owner_mask_on = 0;
  488. U32 next_owner_mask_off = 0;
  489. if (root_selected)
  490. {
  491. valid_base_perms = gSelectMgr.selectGetPerm(PERM_BASE,
  492. &base_mask_on,
  493. &base_mask_off);
  494. valid_owner_perms = gSelectMgr.selectGetPerm(PERM_OWNER,
  495. &owner_mask_on,
  496. &owner_mask_off);
  497. valid_group_perms = gSelectMgr.selectGetPerm(PERM_GROUP,
  498. &group_mask_on,
  499. &group_mask_off);
  500. valid_everyone_perms = gSelectMgr.selectGetPerm(PERM_EVERYONE,
  501. &everyone_mask_on,
  502. &everyone_mask_off);
  503. valid_next_perms = gSelectMgr.selectGetPerm(PERM_NEXT_OWNER,
  504. &next_owner_mask_on,
  505. &next_owner_mask_off);
  506. }
  507. else if (is_one_object)
  508. {
  509. LLSelectNode* node = selection->getFirstNode();
  510. if (node && node->mValid)
  511. {
  512. valid_base_perms = valid_owner_perms = valid_group_perms =
  513. valid_everyone_perms = valid_next_perms = true;
  514. base_mask_on = node->mPermissions->getMaskBase();
  515. owner_mask_on = node->mPermissions->getMaskOwner();
  516. group_mask_on = node->mPermissions->getMaskGroup();
  517. everyone_mask_on = node->mPermissions->getMaskEveryone();
  518. next_owner_mask_on = node->mPermissions->getMaskNextOwner();
  519. }
  520. }
  521. bool export_support = gAgent.regionHasExportPermSupport();
  522. static LLCachedControl<bool> debug_permissions(gSavedSettings,
  523. "DebugPermissions");
  524. if (debug_permissions)
  525. {
  526. std::string perm_string;
  527. if (valid_base_perms)
  528. {
  529. perm_string = "B: " + mask_to_string(base_mask_on,
  530. export_support);
  531. mTextDebugPermB->setText(perm_string);
  532. mTextDebugPermB->setVisible(true);
  533. if (valid_owner_perms)
  534. {
  535. perm_string = "O: " + mask_to_string(owner_mask_on,
  536. export_support);
  537. mTextDebugPermO->setText(perm_string);
  538. }
  539. mTextDebugPermO->setVisible(valid_owner_perms);
  540. if (valid_group_perms)
  541. {
  542. perm_string = "G: " + mask_to_string(group_mask_on);
  543. mTextDebugPermG->setText(perm_string);
  544. }
  545. mTextDebugPermG->setVisible(valid_group_perms);
  546. if (valid_everyone_perms)
  547. {
  548. perm_string = "E: " + mask_to_string(everyone_mask_on,
  549. export_support);
  550. mTextDebugPermE->setText(perm_string);
  551. }
  552. mTextDebugPermE->setVisible(valid_everyone_perms);
  553. if (valid_next_perms)
  554. {
  555. perm_string = "N: " + mask_to_string(next_owner_mask_on,
  556. export_support);
  557. mTextDebugPermN->setText(perm_string);
  558. }
  559. mTextDebugPermN->setVisible(valid_next_perms);
  560. }
  561. U32 flag_mask = 0x0;
  562. if (objectp->permMove()) flag_mask |= PERM_MOVE;
  563. if (objectp->permModify()) flag_mask |= PERM_MODIFY;
  564. if (objectp->permCopy()) flag_mask |= PERM_COPY;
  565. if (objectp->permTransfer()) flag_mask |= PERM_TRANSFER;
  566. perm_string = "F: " + mask_to_string(flag_mask);
  567. mTextDebugPermF->setText(perm_string);
  568. mTextDebugPermF->setVisible(true);
  569. }
  570. else
  571. {
  572. mTextDebugPermB->setVisible(false);
  573. mTextDebugPermO->setVisible(false);
  574. mTextDebugPermG->setVisible(false);
  575. mTextDebugPermE->setVisible(false);
  576. mTextDebugPermN->setVisible(false);
  577. mTextDebugPermF->setVisible(false);
  578. }
  579. bool has_change_perm_ability = false;
  580. bool has_change_sale_ability = false;
  581. if (valid_base_perms && is_nonpermanent_enforced &&
  582. (self_owned ||
  583. (group_owned && gAgent.hasPowerInGroup(group_id,
  584. GP_OBJECT_MANIPULATE))))
  585. {
  586. has_change_perm_ability = true;
  587. }
  588. if (valid_base_perms && is_nonpermanent_enforced &&
  589. (self_owned ||
  590. (group_owned && gAgent.hasPowerInGroup(group_id,
  591. GP_OBJECT_SET_SALE))))
  592. {
  593. has_change_sale_ability = true;
  594. }
  595. if (!has_change_perm_ability && !has_change_sale_ability && !root_selected)
  596. {
  597. // ...must select root to choose permissions
  598. mTextPermissionsModify->setValue(MODIFY_INFO_STRINGS[6]);
  599. }
  600. if (has_change_perm_ability)
  601. {
  602. mCheckShareWithGroup->setEnabled(true);
  603. mCheckAllowEveryoneMove->setEnabled(owner_mask_on & PERM_MOVE);
  604. mCheckAllowEveryoneCopy->setEnabled((owner_mask_on & PERM_COPY) &&
  605. (owner_mask_on & PERM_TRANSFER));
  606. }
  607. else
  608. {
  609. mCheckShareWithGroup->setEnabled(false);
  610. mCheckAllowEveryoneMove->setEnabled(false);
  611. mCheckAllowEveryoneCopy->setEnabled(false);
  612. }
  613. mCheckAllowEveryoneExport->setVisible(export_support);
  614. if (export_support)
  615. {
  616. bool can_export = self_owned && mCreatorID == mOwnerID &&
  617. can_set_export(base_mask_on, owner_mask_on,
  618. next_owner_mask_on);
  619. if (can_export)
  620. {
  621. // Also check that the applied textures can be exported...
  622. for (U32 i = 0, count = objectp->getNumTEs();
  623. can_export && i < count; ++i)
  624. {
  625. if (LLTextureEntry* tep = objectp->getTE(i))
  626. {
  627. if (!HBObjectBackup::validateAssetPerms(tep->getID()))
  628. {
  629. can_export = false;
  630. break;
  631. }
  632. }
  633. }
  634. }
  635. #if 0 // We do not care about the object contents for now, since we never
  636. // export it !... Plus, it would be possible to set PERM_EXPORT on that
  637. // object without ever checking for its contents, by simply taking it
  638. // back to the inventory and setting the export flag from the inventory
  639. // asset properties floater instead... Just like you can set Copy-OK an
  640. // object containing no-copy assets from the inventory while you can't
  641. // (because of no-copy contents checking) while rezzed...
  642. // <rant>This permissions logic has always been utterly flawed and
  643. // buggy in both SL and OpenSIM, by lack of a recursive checking of
  644. // inventory assets contents permissions (plus, forcing a no-mod flag
  645. // on a container object while it is rezzed just because it contains
  646. // no-mod assets is also a *serious* BUG: the mod-ok flag should NEVER
  647. // recurse !)</rant>
  648. // The object's inventory must have EXPORT.
  649. objectp->getInventoryContents(objects);
  650. for (LLInventoryObject::object_list_t::iterator it = objects.begin(),
  651. end = objects.end();
  652. can_export && it != end ; ++it)
  653. {
  654. LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(i->get());
  655. can_export = perms_allow_export(item->getPermissions());
  656. }
  657. #endif
  658. mCheckAllowEveryoneExport->setEnabled(can_export);
  659. }
  660. if (has_change_sale_ability && (owner_mask_on & PERM_TRANSFER))
  661. {
  662. mCheckForSale->setEnabled(can_transfer ||
  663. (!can_transfer && num_for_sale));
  664. // Set the checkbox to tentative if the prices of each object selected
  665. // are not the same.
  666. mCheckForSale->setTentative(is_for_sale_mixed);
  667. mRadioSaleType->setEnabled(num_for_sale && can_transfer &&
  668. !is_sale_price_mixed);
  669. mTextNextOwnerCan->setEnabled(true);
  670. mCheckNextCanModify->setEnabled(base_mask_on & PERM_MODIFY);
  671. mCheckNextCanCopy->setEnabled(base_mask_on & PERM_COPY);
  672. mCheckNextCanTransfer->setEnabled(next_owner_mask_on & PERM_COPY);
  673. }
  674. else
  675. {
  676. mCheckForSale->setEnabled(false);
  677. mRadioSaleType->setEnabled(false);
  678. mTextNextOwnerCan->setEnabled(false);
  679. mCheckNextCanModify->setEnabled(false);
  680. mCheckNextCanCopy->setEnabled(false);
  681. mCheckNextCanTransfer->setEnabled(false);
  682. }
  683. if (valid_group_perms)
  684. {
  685. if ((group_mask_on & PERM_COPY) && (group_mask_on & PERM_MODIFY) &&
  686. (group_mask_on & PERM_MOVE))
  687. {
  688. mCheckShareWithGroup->set(true);
  689. mCheckShareWithGroup->setTentative(false);
  690. mButtonDeed->setEnabled(!group_owned && can_transfer &&
  691. (owner_mask_on & PERM_TRANSFER) &&
  692. gAgent.hasPowerInGroup(group_id,
  693. GP_OBJECT_DEED));
  694. }
  695. else if ((group_mask_off & PERM_COPY) &&
  696. (group_mask_off & PERM_MODIFY) &&
  697. (group_mask_off & PERM_MOVE))
  698. {
  699. mCheckShareWithGroup->set(false);
  700. mCheckShareWithGroup->setTentative(false);
  701. mButtonDeed->setEnabled(false);
  702. }
  703. else
  704. {
  705. mCheckShareWithGroup->set(true);
  706. mCheckShareWithGroup->setTentative(true);
  707. mButtonDeed->setEnabled(!group_owned && can_transfer &&
  708. (group_mask_on & PERM_MOVE) &&
  709. (owner_mask_on & PERM_TRANSFER) &&
  710. gAgent.hasPowerInGroup(group_id,
  711. GP_OBJECT_DEED));
  712. }
  713. }
  714. if (valid_everyone_perms)
  715. {
  716. // Move
  717. if (everyone_mask_on & PERM_MOVE)
  718. {
  719. mCheckAllowEveryoneMove->set(true);
  720. mCheckAllowEveryoneMove->setTentative(false);
  721. }
  722. else if (everyone_mask_off & PERM_MOVE)
  723. {
  724. mCheckAllowEveryoneMove->set(false);
  725. mCheckAllowEveryoneMove->setTentative(false);
  726. }
  727. else
  728. {
  729. mCheckAllowEveryoneMove->set(true);
  730. mCheckAllowEveryoneMove->setTentative(true);
  731. }
  732. // Copy == everyone can't copy
  733. if (everyone_mask_on & PERM_COPY)
  734. {
  735. mCheckAllowEveryoneCopy->set(true);
  736. mCheckAllowEveryoneCopy->setTentative(!can_copy || !can_transfer);
  737. }
  738. else if (everyone_mask_off & PERM_COPY)
  739. {
  740. mCheckAllowEveryoneCopy->set(false);
  741. mCheckAllowEveryoneCopy->setTentative(false);
  742. }
  743. else
  744. {
  745. mCheckAllowEveryoneCopy->set(true);
  746. mCheckAllowEveryoneCopy->setTentative(true);
  747. }
  748. // Export
  749. if (export_support && (everyone_mask_on & PERM_EXPORT) != 0)
  750. {
  751. mCheckAllowEveryoneExport->set(true);
  752. mCheckAllowEveryoneExport->setTentative(false);
  753. }
  754. else if (!export_support || (everyone_mask_off & PERM_EXPORT) != 0)
  755. {
  756. mCheckAllowEveryoneExport->set(false);
  757. mCheckAllowEveryoneExport->setTentative(false);
  758. }
  759. else
  760. {
  761. mCheckAllowEveryoneExport->set(true);
  762. mCheckAllowEveryoneExport->setTentative(true);
  763. }
  764. }
  765. if (valid_next_perms)
  766. {
  767. // Modify == next owner canot modify
  768. if (next_owner_mask_on & PERM_MODIFY)
  769. {
  770. mCheckNextCanModify->set(true);
  771. mCheckNextCanModify->setTentative(false);
  772. }
  773. else if (next_owner_mask_off & PERM_MODIFY)
  774. {
  775. mCheckNextCanModify->set(false);
  776. mCheckNextCanModify->setTentative(false);
  777. }
  778. else
  779. {
  780. mCheckNextCanModify->set(true);
  781. mCheckNextCanModify->setTentative(true);
  782. }
  783. // Copy == next owner cannot copy
  784. if (next_owner_mask_on & PERM_COPY)
  785. {
  786. mCheckNextCanCopy->set(true);
  787. mCheckNextCanCopy->setTentative(!can_copy);
  788. }
  789. else if (next_owner_mask_off & PERM_COPY)
  790. {
  791. mCheckNextCanCopy->set(false);
  792. mCheckNextCanCopy->setTentative(false);
  793. }
  794. else
  795. {
  796. mCheckNextCanCopy->set(true);
  797. mCheckNextCanCopy->setTentative(true);
  798. }
  799. // Transfer == next owner cannot transfer
  800. if (next_owner_mask_on & PERM_TRANSFER)
  801. {
  802. mCheckNextCanTransfer->set(true);
  803. mCheckNextCanTransfer->setTentative(!can_transfer);
  804. }
  805. else if (next_owner_mask_off & PERM_TRANSFER)
  806. {
  807. mCheckNextCanTransfer->set(false);
  808. mCheckNextCanTransfer->setTentative(false);
  809. }
  810. else
  811. {
  812. mCheckNextCanTransfer->set(true);
  813. mCheckNextCanTransfer->setTentative(true);
  814. }
  815. }
  816. // reflect sale information
  817. LLSaleInfo sale_info;
  818. bool valid_sale_info = gSelectMgr.selectGetSaleInfo(sale_info);
  819. LLSaleInfo::EForSale sale_type = sale_info.getSaleType();
  820. if (valid_sale_info)
  821. {
  822. mRadioSaleType->setSelectedIndex((S32)sale_type - 1);
  823. // unfortunately this doesn't do anything at the moment:
  824. mRadioSaleType->setTentative(false);
  825. }
  826. else
  827. {
  828. // default option is sell copy, determined to be safest
  829. mRadioSaleType->setSelectedIndex((S32)LLSaleInfo::FS_COPY - 1);
  830. // unfortunately this doesn't do anything at the moment:
  831. mRadioSaleType->setTentative(true);
  832. }
  833. mCheckForSale->setValue(num_for_sale != 0);
  834. // HACK: There are some old objects in world that are set for sale, but are
  835. // no-transfer. We need to let users turn for-sale off, but only if
  836. // for-sale is set.
  837. bool cannot_actually_sell = !can_transfer ||
  838. (!can_copy &&
  839. sale_type == LLSaleInfo::FS_COPY);
  840. if (num_for_sale && has_change_sale_ability && cannot_actually_sell)
  841. {
  842. mCheckForSale->setEnabled(true);
  843. }
  844. if (selection->isAttachment())
  845. {
  846. mCheckForSale->setEnabled(false);
  847. mRadioSaleType->setEnabled(false);
  848. mEditorCost->setEnabled(false);
  849. }
  850. // Check search status of objects
  851. bool all_volume = gSelectMgr.selectionAllPCode(LL_PCODE_VOLUME);
  852. bool include_in_search;
  853. bool all_include_in_search = gSelectMgr.selectionGetIncludeInSearch(&include_in_search);
  854. mCheckShowInSearch->setEnabled(has_change_sale_ability && all_volume);
  855. mCheckShowInSearch->setValue(include_in_search);
  856. mCheckShowInSearch->setTentative(!all_include_in_search);
  857. // Click action (touch, sit, buy)
  858. U8 click_action = 0;
  859. if (gSelectMgr.selectionGetClickAction(&click_action))
  860. {
  861. mComboClickAction->setCurrentByIndex((S32)click_action);
  862. }
  863. mTextClickAction->setEnabled(is_perm_modify && all_volume &&
  864. is_nonpermanent_enforced);
  865. mComboClickAction->setEnabled(is_perm_modify && all_volume &&
  866. is_nonpermanent_enforced);
  867. }
  868. //static
  869. void LLPanelPermissions::onClickClaim(void*)
  870. {
  871. // try to claim ownership
  872. gSelectMgr.sendOwner(gAgentID, gAgent.getGroupID());
  873. }
  874. //static
  875. void LLPanelPermissions::onClickRelease(void*)
  876. {
  877. // try to release ownership
  878. gSelectMgr.sendOwner(LLUUID::null, LLUUID::null);
  879. }
  880. //static
  881. void LLPanelPermissions::onClickCreator(void* data)
  882. {
  883. LLPanelPermissions* self = (LLPanelPermissions*)data;
  884. LLFloaterAvatarInfo::showFromObject(self->mCreatorID);
  885. }
  886. //static
  887. void LLPanelPermissions::onClickOwner(void* data)
  888. {
  889. LLPanelPermissions* self = (LLPanelPermissions*)data;
  890. if (gSelectMgr.selectIsGroupOwned())
  891. {
  892. LLUUID group_id;
  893. gSelectMgr.selectGetGroup(group_id);
  894. LLFloaterGroupInfo::showFromUUID(group_id);
  895. }
  896. else
  897. {
  898. //MK
  899. if (gRLenabled &&
  900. (gRLInterface.mContainsShownames ||
  901. gRLInterface.mContainsShownametags))
  902. {
  903. return;
  904. }
  905. //mk
  906. LLFloaterAvatarInfo::showFromObject(self->mOwnerID);
  907. }
  908. }
  909. void LLPanelPermissions::onClickGroup(void* data)
  910. {
  911. LLPanelPermissions* panelp = (LLPanelPermissions*)data;
  912. LLUUID owner_id;
  913. std::string name;
  914. bool owners_identical = gSelectMgr.selectGetOwner(owner_id, name);
  915. if (owners_identical && owner_id == gAgentID)
  916. {
  917. LLFloaterGroupPicker* fg = LLFloaterGroupPicker::show(cbGroupID, data);
  918. if (gFloaterViewp)
  919. {
  920. LLFloater* parentp = gFloaterViewp->getParentFloater(panelp);
  921. if (fg && parentp)
  922. {
  923. LLRect rect;
  924. rect = gFloaterViewp->findNeighboringPosition(parentp, fg);
  925. fg->setOrigin(rect.mLeft, rect.mBottom);
  926. parentp->addDependentFloater(fg);
  927. }
  928. }
  929. }
  930. }
  931. //static
  932. void LLPanelPermissions::cbGroupID(LLUUID group_id, void* data)
  933. {
  934. LLPanelPermissions* self = (LLPanelPermissions*)data;
  935. if (self)
  936. {
  937. self->mNameBoxGroupName->setNameID(group_id, true);
  938. }
  939. gSelectMgr.sendGroup(group_id);
  940. }
  941. bool callback_deed_to_group(const LLSD& notification, const LLSD& response)
  942. {
  943. S32 option = LLNotification::getSelectedOption(notification, response);
  944. if (0 == option)
  945. {
  946. LLUUID group_id;
  947. bool groups_identical = gSelectMgr.selectGetGroup(group_id);
  948. if (group_id.notNull() && groups_identical &&
  949. gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED))
  950. {
  951. gSelectMgr.sendOwner(LLUUID::null, group_id, false);
  952. }
  953. }
  954. return false;
  955. }
  956. void LLPanelPermissions::onClickDeedToGroup(void* data)
  957. {
  958. gNotifications.add("DeedObjectToGroup", LLSD(), LLSD(),
  959. callback_deed_to_group);
  960. }
  961. ///----------------------------------------------------------------------------
  962. /// Permissions checkboxes
  963. ///----------------------------------------------------------------------------
  964. //static
  965. void LLPanelPermissions::onCommitPerm(LLUICtrl* ctrl, void* data, U8 field,
  966. U32 perm)
  967. {
  968. LLViewerObject* object = gSelectMgr.getSelection()->getFirstRootObject();
  969. if (object && ctrl)
  970. {
  971. LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl;
  972. bool new_state = check->get();
  973. gSelectMgr.selectionSetObjectPermissions(field, new_state, perm);
  974. }
  975. }
  976. //static
  977. void LLPanelPermissions::onCommitGroupShare(LLUICtrl* ctrl, void* data)
  978. {
  979. onCommitPerm(ctrl, data, PERM_GROUP, PERM_MODIFY | PERM_MOVE | PERM_COPY);
  980. }
  981. //static
  982. void LLPanelPermissions::onCommitEveryoneExport(LLUICtrl* ctrl, void* data)
  983. {
  984. onCommitPerm(ctrl, data, PERM_EVERYONE, PERM_EXPORT);
  985. }
  986. //static
  987. void LLPanelPermissions::onCommitEveryoneMove(LLUICtrl* ctrl, void* data)
  988. {
  989. onCommitPerm(ctrl, data, PERM_EVERYONE, PERM_MOVE);
  990. }
  991. //static
  992. void LLPanelPermissions::onCommitEveryoneCopy(LLUICtrl* ctrl, void* data)
  993. {
  994. onCommitPerm(ctrl, data, PERM_EVERYONE, PERM_COPY);
  995. }
  996. //static
  997. void LLPanelPermissions::onCommitNextOwnerModify(LLUICtrl* ctrl, void* data)
  998. {
  999. onCommitPerm(ctrl, data, PERM_NEXT_OWNER, PERM_MODIFY);
  1000. }
  1001. //static
  1002. void LLPanelPermissions::onCommitNextOwnerCopy(LLUICtrl* ctrl, void* data)
  1003. {
  1004. onCommitPerm(ctrl, data, PERM_NEXT_OWNER, PERM_COPY);
  1005. }
  1006. //static
  1007. void LLPanelPermissions::onCommitNextOwnerTransfer(LLUICtrl* ctrl, void* data)
  1008. {
  1009. onCommitPerm(ctrl, data, PERM_NEXT_OWNER, PERM_TRANSFER);
  1010. }
  1011. //static
  1012. void LLPanelPermissions::onCommitName(LLUICtrl*, void* data)
  1013. {
  1014. LLPanelPermissions* self = (LLPanelPermissions*)data;
  1015. if (!self) return;
  1016. const std::string& name = self->mEditorObjectName->getText();
  1017. gSelectMgr.selectionSetObjectName(name);
  1018. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  1019. if (selection->isAttachment() && selection->getNumNodes() == 1 &&
  1020. !name.empty())
  1021. {
  1022. const LLUUID& id = selection->getFirstObject()->getAttachmentItemID();
  1023. if (id.isNull()) return;
  1024. LLViewerInventoryItem* item = gInventory.getItem(id);
  1025. if (item)
  1026. {
  1027. LLPointer<LLViewerInventoryItem> new_item =
  1028. new LLViewerInventoryItem(item);
  1029. new_item->rename(name);
  1030. new_item->updateServer(false);
  1031. gInventory.updateItem(new_item);
  1032. gInventory.notifyObservers();
  1033. }
  1034. }
  1035. }
  1036. //static
  1037. void LLPanelPermissions::onCommitDesc(LLUICtrl*, void* data)
  1038. {
  1039. LLPanelPermissions* self = (LLPanelPermissions*)data;
  1040. if (!self) return;
  1041. const std::string& desc = self->mEditorObjectDesc->getText();
  1042. gSelectMgr.selectionSetObjectDescription(desc);
  1043. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  1044. if (selection->isAttachment() && selection->getNumNodes() == 1 &&
  1045. !desc.empty())
  1046. {
  1047. const LLUUID& id = selection->getFirstObject()->getAttachmentItemID();
  1048. if (id.isNull()) return;
  1049. LLViewerInventoryItem* item = gInventory.getItem(id);
  1050. if (item)
  1051. {
  1052. LLPointer<LLViewerInventoryItem> new_item =
  1053. new LLViewerInventoryItem(item);
  1054. new_item->setDescription(desc);
  1055. new_item->updateServer(false);
  1056. gInventory.updateItem(new_item);
  1057. gInventory.notifyObservers();
  1058. }
  1059. }
  1060. }
  1061. //static
  1062. void LLPanelPermissions::onCommitSaleInfo(LLUICtrl*, void* data)
  1063. {
  1064. LLPanelPermissions* self = (LLPanelPermissions*)data;
  1065. if (self)
  1066. {
  1067. self->setAllSaleInfo();
  1068. }
  1069. }
  1070. //static
  1071. void LLPanelPermissions::onCommitSaleType(LLUICtrl*, void* data)
  1072. {
  1073. LLPanelPermissions* self = (LLPanelPermissions*)data;
  1074. if (self)
  1075. {
  1076. self->setAllSaleInfo();
  1077. }
  1078. }
  1079. void LLPanelPermissions::setAllSaleInfo()
  1080. {
  1081. LLSaleInfo::EForSale sale_type = LLSaleInfo::FS_NOT;
  1082. // Set the sale type if the object(s) are for sale.
  1083. if (mCheckForSale->get())
  1084. {
  1085. switch (mRadioSaleType->getSelectedIndex())
  1086. {
  1087. case 0:
  1088. sale_type = LLSaleInfo::FS_ORIGINAL;
  1089. break;
  1090. case 2:
  1091. sale_type = LLSaleInfo::FS_CONTENTS;
  1092. break;
  1093. default:
  1094. sale_type = LLSaleInfo::FS_COPY;
  1095. }
  1096. }
  1097. S32 price = -1;
  1098. // Do not extract the price if it is labeled as MIXED or is empty.
  1099. const std::string& price_string = mEditorCost->getText();
  1100. if (!price_string.empty() && price_string != mCostMixed &&
  1101. price_string != mSaleMixed)
  1102. {
  1103. price = atoi(price_string.c_str());
  1104. }
  1105. else
  1106. {
  1107. price = DEFAULT_PRICE;
  1108. }
  1109. // If somehow an invalid price, turn the sale off.
  1110. if (price < 0)
  1111. {
  1112. sale_type = LLSaleInfo::FS_NOT;
  1113. }
  1114. // Force the sale price of not-for-sale items to DEFAULT_PRICE.
  1115. if (sale_type == LLSaleInfo::FS_NOT)
  1116. {
  1117. price = DEFAULT_PRICE;
  1118. }
  1119. LLSaleInfo old_sale_info;
  1120. gSelectMgr.selectGetSaleInfo(old_sale_info);
  1121. bool was_for_sale = old_sale_info.isForSale();
  1122. // Pack up the sale info and send the update.
  1123. LLSaleInfo sale_info(sale_type, price);
  1124. gSelectMgr.selectionSetObjectSaleInfo(sale_info);
  1125. bool set_for_sale = sale_info.isForSale();
  1126. // Note: won't work right if a root and non-root are both single-
  1127. // selected (here and other places).
  1128. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  1129. bool is_perm_modify = gSelectMgr.selectGetModify() ||
  1130. (selection->getFirstRootNode() &&
  1131. gSelectMgr.selectGetRootsModify());
  1132. bool is_nonpermanent_enforced =
  1133. gSelectMgr.selectGetNonPermanentEnforced() ||
  1134. (selection->getFirstRootNode() &&
  1135. gSelectMgr.selectGetRootsNonPermanentEnforced());
  1136. if (!is_perm_modify || !is_nonpermanent_enforced)
  1137. {
  1138. return;
  1139. }
  1140. U8 old_click_action = 0;
  1141. gSelectMgr.selectionGetClickAction(&old_click_action);
  1142. if (old_click_action == CLICK_ACTION_BUY && was_for_sale && !set_for_sale)
  1143. {
  1144. // If turned off for-sale, make sure click-action buy is turned off as
  1145. // well
  1146. gSelectMgr.selectionSetClickAction(CLICK_ACTION_TOUCH);
  1147. }
  1148. else if (old_click_action == CLICK_ACTION_TOUCH && !was_for_sale &&
  1149. set_for_sale)
  1150. {
  1151. // If just turning on for-sale, preemptively turn on one-click buy
  1152. // unless user has a different click action set
  1153. gSelectMgr.selectionSetClickAction(CLICK_ACTION_BUY);
  1154. }
  1155. }
  1156. struct LLSelectionPayable final : public LLSelectedObjectFunctor
  1157. {
  1158. bool apply(LLViewerObject* obj) override
  1159. {
  1160. // can pay if you or your parent has money() event in script
  1161. LLViewerObject* parent = (LLViewerObject*)obj->getParent();
  1162. return obj->flagTakesMoney() || (parent && parent->flagTakesMoney());
  1163. }
  1164. };
  1165. //static
  1166. void LLPanelPermissions::onCommitClickAction(LLUICtrl* ctrl, void*)
  1167. {
  1168. LLComboBox* box = (LLComboBox*)ctrl;
  1169. if (!box) return;
  1170. U8 click_action = (U8)box->getCurrentIndex();
  1171. if (click_action == CLICK_ACTION_BUY)
  1172. {
  1173. LLSaleInfo sale_info;
  1174. gSelectMgr.selectGetSaleInfo(sale_info);
  1175. if (!sale_info.isForSale())
  1176. {
  1177. gNotifications.add("CantSetBuyObject");
  1178. // Set click action back to its old value
  1179. U8 click_action = 0;
  1180. gSelectMgr.selectionGetClickAction(&click_action);
  1181. box->setCurrentByIndex((S32)click_action);
  1182. return;
  1183. }
  1184. }
  1185. else if (click_action == CLICK_ACTION_PAY)
  1186. {
  1187. // Verify object has script with money() handler
  1188. LLSelectionPayable payable;
  1189. bool can_pay = gSelectMgr.getSelection()->applyToObjects(&payable);
  1190. if (!can_pay)
  1191. {
  1192. // Warn, but do it anyway.
  1193. gNotifications.add("ClickActionNotPayable");
  1194. }
  1195. }
  1196. gSelectMgr.selectionSetClickAction(click_action);
  1197. }
  1198. //static
  1199. void LLPanelPermissions::onCommitIncludeInSearch(LLUICtrl* ctrl, void*)
  1200. {
  1201. LLCheckBoxCtrl* box = (LLCheckBoxCtrl*)ctrl;
  1202. llassert(box);
  1203. gSelectMgr.selectionSetIncludeInSearch(box->get());
  1204. }