llfloaterland.cpp 95 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409
  1. /**
  2. * @file llfloaterland.cpp
  3. * @brief "About land" floater, allowing display and editing of land parcel
  4. * properties.
  5. *
  6. * $LicenseInfo:firstyear=2002&license=viewergpl$
  7. *
  8. * Copyright (c) 2002-2009, Linden Research, Inc.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #include "llviewerprecompiledheaders.h"
  34. #include <sstream>
  35. #include <time.h>
  36. #include "llfloaterland.h"
  37. #include "llbutton.h"
  38. #include "llcachename.h"
  39. #include "llcheckboxctrl.h"
  40. #include "llcombobox.h"
  41. #include "llexperiencecache.h"
  42. #include "lllineeditor.h"
  43. #include "llnamelistctrl.h"
  44. #include "llradiogroup.h"
  45. #include "llspinctrl.h"
  46. #include "lltabcontainer.h"
  47. #include "lltextbox.h"
  48. #include "lltrans.h"
  49. #include "lluictrlfactory.h"
  50. #include "llagent.h"
  51. #include "llappviewer.h" // For gFrameTimeSeconds
  52. #include "llfloaterauction.h"
  53. #include "llfloateravatarinfo.h"
  54. #include "llfloateravatarpicker.h"
  55. #include "llfloatergroups.h"
  56. #include "llfloatergroupinfo.h"
  57. #include "llpanelexperiencelisteditor.h"
  58. #include "llpanellandaudio.h"
  59. #include "hbpanellandenvironment.h"
  60. #include "llpanellandmedia.h"
  61. //MK
  62. #include "mkrlinterface.h"
  63. //mk
  64. #include "llselectmgr.h"
  65. #include "lltexturectrl.h"
  66. #include "lluserauth.h"
  67. #include "llviewercontrol.h"
  68. #include "llviewermessage.h" // For formatted_time()
  69. #include "llviewerparcelmgr.h"
  70. #include "llviewerregion.h"
  71. #include "llviewerstats.h"
  72. #include "llviewertexteditor.h"
  73. #include "roles_constants.h"
  74. static const std::string OWNER_ONLINE = "0";
  75. static const std::string OWNER_OFFLINE = "1";
  76. static const std::string OWNER_GROUP = "2";
  77. // Constants used in callbacks below; syntactic sugar.
  78. constexpr bool BUY_GROUP_LAND = true;
  79. constexpr bool BUY_PERSONAL_LAND = false;
  80. // Statics
  81. LLFloaterLandParcelSelectObserver* LLFloaterLand::sObserver = NULL;
  82. S32 LLFloaterLand::sLastTab = 0;
  83. // Helper function
  84. static std::string plain_text_duration(S32 seconds)
  85. {
  86. std:: string tmp;
  87. if (seconds <= 0)
  88. {
  89. return tmp;
  90. }
  91. S32 amount = seconds;
  92. if (seconds >= 7200)
  93. {
  94. tmp = "hours";
  95. amount /= 3600;
  96. }
  97. else if (seconds >= 3600)
  98. {
  99. tmp = "hour";
  100. amount = 1;
  101. }
  102. else if (seconds >= 120)
  103. {
  104. tmp = "minutes";
  105. amount /= 60;
  106. }
  107. else if (seconds >= 60)
  108. {
  109. tmp = "minute";
  110. amount = 1;
  111. }
  112. else if (seconds > 1)
  113. {
  114. tmp = "seconds";
  115. }
  116. else
  117. {
  118. tmp = "second";
  119. }
  120. tmp = "%d " + LLTrans::getString(tmp);
  121. return llformat(tmp.c_str(), amount);
  122. }
  123. ///////////////////////////////////////////////////////////////////////////////
  124. // Local classes
  125. ///////////////////////////////////////////////////////////////////////////////
  126. // LLFloaterLandParcelSelectObserver
  127. class LLFloaterLandParcelSelectObserver final
  128. : public LLParcelSelectionObserver
  129. {
  130. public:
  131. void changed() override
  132. {
  133. LLFloaterLand::getInstance()->refresh();
  134. }
  135. };
  136. // LLFloaterBanDuration
  137. class LLFloaterBanDuration final : public LLFloater
  138. {
  139. public:
  140. ~LLFloaterBanDuration() override;
  141. bool postBuild() override;
  142. typedef void(*callback_t)(const uuid_vec_t&, S32, void*);
  143. // Call this to set the ban duration on a list of avatars. The callback
  144. // function will be called with the avatar UUIDs list and an expiration
  145. // date (in seconds since UNIX epoch) for a temporary ban or 0 for a
  146. // permanent ban.
  147. static LLFloaterBanDuration* show(const uuid_vec_t& ids,
  148. callback_t callback, void* userdata);
  149. private:
  150. // Do not call this directly. Use the show() method above.
  151. LLFloaterBanDuration(const uuid_vec_t& ids, callback_t callback,
  152. void* userdata);
  153. static void onBtnBan(void* userdata);
  154. static void onBtnCancel(void* userdata);
  155. static void onRadioCheck(LLUICtrl* ctrl, void* userdata);
  156. private:
  157. LLSpinCtrl* mDurationSpin;
  158. void (*mCallback)(const uuid_vec_t& ids,
  159. S32 duration, void* userdata);
  160. void* mCallbackUserdata;
  161. uuid_vec_t mAvatarIds;
  162. bool mPermanentBan;
  163. typedef fast_hset<LLFloaterBanDuration*> instances_list_t;
  164. static instances_list_t sInstances;
  165. };
  166. LLFloaterBanDuration::instances_list_t LLFloaterBanDuration::sInstances;
  167. //static
  168. LLFloaterBanDuration* LLFloaterBanDuration::show(const uuid_vec_t& ids,
  169. callback_t callback,
  170. void* userdata)
  171. {
  172. LLFloaterBanDuration* self = NULL;
  173. for (instances_list_t::iterator it = sInstances.begin(),
  174. end = sInstances.end();
  175. it != end; ++it)
  176. {
  177. LLFloaterBanDuration* instance = *it;
  178. if (instance && instance->mCallback == callback &&
  179. instance->mCallbackUserdata == userdata)
  180. {
  181. self = instance;
  182. break;
  183. }
  184. }
  185. if (!self)
  186. {
  187. self = new LLFloaterBanDuration(ids, callback, userdata);
  188. }
  189. self->open();
  190. return self;
  191. }
  192. LLFloaterBanDuration::LLFloaterBanDuration(const uuid_vec_t& ids,
  193. callback_t callback, void* userdata)
  194. : mAvatarIds(ids),
  195. mCallback(callback),
  196. mCallbackUserdata(userdata),
  197. mPermanentBan(true)
  198. {
  199. sInstances.insert(this);
  200. LLUICtrlFactory::getInstance()->buildFloater(this,
  201. "floater_ban_duration.xml");
  202. }
  203. LLFloaterBanDuration::~LLFloaterBanDuration()
  204. {
  205. sInstances.erase(this);
  206. }
  207. bool LLFloaterBanDuration::postBuild()
  208. {
  209. mDurationSpin = getChild<LLSpinCtrl>("ban_hours");
  210. mDurationSpin->setEnabled(false);
  211. LLRadioGroup* radio = getChild<LLRadioGroup>("ban_type");
  212. radio->selectNthItem(0);
  213. radio->setCommitCallback(onRadioCheck);
  214. radio->setCallbackUserData(this);
  215. childSetAction("ok_btn", onBtnBan, this);
  216. childSetAction("cancel_btn", onBtnCancel, this);
  217. center();
  218. return true;
  219. }
  220. //static
  221. void LLFloaterBanDuration::onBtnBan(void* userdata)
  222. {
  223. LLFloaterBanDuration* self = (LLFloaterBanDuration*)userdata;
  224. if (self)
  225. {
  226. if (self->mCallback)
  227. {
  228. S32 time = 0;
  229. if (!self->mPermanentBan)
  230. {
  231. time = 3600 * self->mDurationSpin->getValue().asInteger();
  232. LL_DEBUGS("ParcelAccess") << "Ban duration will be: " << time
  233. << " seconds" << LL_ENDL;
  234. time += LLTimer::getEpochSeconds();
  235. }
  236. else
  237. {
  238. LL_DEBUGS("ParcelAccess") << "Ban will be permanent"
  239. << LL_ENDL;
  240. }
  241. LL_DEBUGS("ParcelAccess") << "Requesting ban for the following avatars: ";
  242. for (U32 i = 0, count = self->mAvatarIds.size(); i < count; ++i)
  243. {
  244. if (i > 0)
  245. {
  246. LL_CONT << ", ";
  247. }
  248. LL_CONT << self->mAvatarIds[i];
  249. }
  250. LL_CONT << LL_ENDL;
  251. self->mCallback(self->mAvatarIds, time, self->mCallbackUserdata);
  252. }
  253. self->close();
  254. }
  255. }
  256. //static
  257. void LLFloaterBanDuration::onBtnCancel(void* userdata)
  258. {
  259. LLFloaterBanDuration* self = (LLFloaterBanDuration*)userdata;
  260. if (self)
  261. {
  262. self->close();
  263. }
  264. }
  265. //static
  266. void LLFloaterBanDuration::onRadioCheck(LLUICtrl* ctrl, void* userdata)
  267. {
  268. LLFloaterBanDuration* self = (LLFloaterBanDuration*)userdata;
  269. LLRadioGroup* radio = (LLRadioGroup*)ctrl;
  270. if (self && radio)
  271. {
  272. self->mPermanentBan = radio->getSelectedIndex() == 0;
  273. self->mDurationSpin->setEnabled(!self->mPermanentBan);
  274. }
  275. }
  276. ///////////////////////////////////////////////////////////////////////////////
  277. // LLFloaterLand class proper
  278. ///////////////////////////////////////////////////////////////////////////////
  279. void send_parcel_select_objects(S32 parcel_local_id, U32 return_type,
  280. owners_list_t* return_ids)
  281. {
  282. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  283. if (!region) return;
  284. // Since new highlight will be coming in, drop any highlights
  285. // that exist right now.
  286. gSelectMgr.unhighlightAll();
  287. LLMessageSystem* msg = gMessageSystemp;
  288. msg->newMessageFast(_PREHASH_ParcelSelectObjects);
  289. msg->nextBlockFast(_PREHASH_AgentData);
  290. msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
  291. msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
  292. msg->nextBlockFast(_PREHASH_ParcelData);
  293. msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
  294. msg->addU32Fast(_PREHASH_ReturnType, return_type);
  295. // Throw all return ids into the packet.
  296. // TODO: Check for too many ids.
  297. if (return_ids)
  298. {
  299. for (owners_list_t::iterator it = return_ids->begin(),
  300. end = return_ids->end();
  301. it != end; ++it)
  302. {
  303. msg->nextBlockFast(_PREHASH_ReturnIDs);
  304. msg->addUUIDFast(_PREHASH_ReturnID, (*it));
  305. }
  306. }
  307. else
  308. {
  309. // Put in a null key so that the message is complete.
  310. msg->nextBlockFast(_PREHASH_ReturnIDs);
  311. msg->addUUIDFast(_PREHASH_ReturnID, LLUUID::null);
  312. }
  313. msg->sendReliable(region->getHost());
  314. }
  315. //static
  316. LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects()
  317. {
  318. return getInstance()->mPanelObjects;
  319. }
  320. //static
  321. LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant()
  322. {
  323. return getInstance()->mPanelCovenant;
  324. }
  325. void LLFloaterLand::onOpen()
  326. {
  327. #if 0 // Done automatically when the selected parcel's properties arrive
  328. // (and hence we have the local id).
  329. gViewerParcelMgr.sendParcelAccessListRequest(AL_ACCESS | AL_BAN |
  330. AL_RENTER);
  331. #endif
  332. mParcel = gViewerParcelMgr.getFloatingParcelSelection();
  333. // Refresh even if not over a region so we do not get an uninitialized
  334. // dialog. The dialog is 0-region aware.
  335. refresh();
  336. }
  337. //virtual
  338. void LLFloaterLand::onClose(bool app_quitting)
  339. {
  340. gViewerParcelMgr.removeSelectionObserver(sObserver);
  341. delete sObserver;
  342. sObserver = NULL;
  343. // Might have been showing owned objects
  344. gSelectMgr.unhighlightAll();
  345. // Save which panel we had open
  346. sLastTab = mTabLand->getCurrentPanelIndex();
  347. destroy();
  348. }
  349. LLFloaterLand::LLFloaterLand(const LLSD&)
  350. : mPanelExperiences(NULL),
  351. mPanelEnvironment(NULL)
  352. {
  353. LLCallbackMap::map_t factory_map;
  354. factory_map["land_general_panel"] = LLCallbackMap(createPanelLandGeneral,
  355. this);
  356. factory_map["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant,
  357. this);
  358. factory_map["land_objects_panel"] = LLCallbackMap(createPanelLandObjects,
  359. this);
  360. factory_map["land_options_panel"] = LLCallbackMap(createPanelLandOptions,
  361. this);
  362. factory_map["land_audio_panel"] = LLCallbackMap(createPanelLandAudio,
  363. this);
  364. factory_map["land_media_panel"] = LLCallbackMap(createPanelLandMedia,
  365. this);
  366. factory_map["land_access_panel"] = LLCallbackMap(createPanelLandAccess,
  367. this);
  368. LLUICtrlFactory::getInstance()->buildFloater(this,
  369. "floater_about_land.xml",
  370. &factory_map, false);
  371. sObserver = new LLFloaterLandParcelSelectObserver();
  372. gViewerParcelMgr.addSelectionObserver(sObserver);
  373. }
  374. bool LLFloaterLand::postBuild()
  375. {
  376. mTabLand = getChild<LLTabContainer>("landtab");
  377. // Add the experiences tab if needed
  378. if (gAgent.hasRegionCapability("RegionExperiences"))
  379. {
  380. mPanelExperiences = new LLPanelLandExperiences(mParcel);
  381. mTabLand->addTabPanel(mPanelExperiences,
  382. mPanelExperiences->getLabel());
  383. }
  384. // Add the environment tab if needed
  385. if (gAgent.hasExtendedEnvironment())
  386. {
  387. mPanelEnvironment = new HBPanelLandEnvironment(mParcel);
  388. mTabLand->addTabPanel(mPanelEnvironment,
  389. mPanelEnvironment->getLabel());
  390. }
  391. if (sLastTab < mTabLand->getTabCount())
  392. {
  393. mTabLand->selectTab(sLastTab);
  394. }
  395. else
  396. {
  397. sLastTab = 0;
  398. }
  399. return true;
  400. }
  401. //virtual
  402. LLFloaterLand::~LLFloaterLand()
  403. {
  404. // Release the selection handle
  405. mParcel = NULL;
  406. }
  407. //virtual
  408. void LLFloaterLand::refresh()
  409. {
  410. mPanelGeneral->refresh();
  411. mPanelObjects->refresh();
  412. mPanelOptions->refresh();
  413. mPanelAudio->refresh();
  414. mPanelMedia->refresh();
  415. mPanelAccess->refresh();
  416. mPanelCovenant->refresh();
  417. if (mPanelExperiences)
  418. {
  419. mPanelExperiences->refresh();
  420. }
  421. if (mPanelEnvironment)
  422. {
  423. mPanelEnvironment->refresh();
  424. }
  425. }
  426. void* LLFloaterLand::createPanelLandGeneral(void* data)
  427. {
  428. LLFloaterLand* self = (LLFloaterLand*)data;
  429. self->mPanelGeneral = new LLPanelLandGeneral(self->mParcel);
  430. return self->mPanelGeneral;
  431. }
  432. //static
  433. void* LLFloaterLand::createPanelLandCovenant(void* data)
  434. {
  435. LLFloaterLand* self = (LLFloaterLand*)data;
  436. self->mPanelCovenant = new LLPanelLandCovenant(self->mParcel);
  437. return self->mPanelCovenant;
  438. }
  439. //static
  440. void* LLFloaterLand::createPanelLandObjects(void* data)
  441. {
  442. LLFloaterLand* self = (LLFloaterLand*)data;
  443. self->mPanelObjects = new LLPanelLandObjects(self->mParcel);
  444. return self->mPanelObjects;
  445. }
  446. //static
  447. void* LLFloaterLand::createPanelLandOptions(void* data)
  448. {
  449. LLFloaterLand* self = (LLFloaterLand*)data;
  450. self->mPanelOptions = new LLPanelLandOptions(self->mParcel);
  451. return self->mPanelOptions;
  452. }
  453. //static
  454. void* LLFloaterLand::createPanelLandAudio(void* data)
  455. {
  456. LLFloaterLand* self = (LLFloaterLand*)data;
  457. self->mPanelAudio = new LLPanelLandAudio(self->mParcel);
  458. return self->mPanelAudio;
  459. }
  460. //static
  461. void* LLFloaterLand::createPanelLandMedia(void* data)
  462. {
  463. LLFloaterLand* self = (LLFloaterLand*)data;
  464. self->mPanelMedia = new LLPanelLandMedia(self->mParcel);
  465. return self->mPanelMedia;
  466. }
  467. //static
  468. void* LLFloaterLand::createPanelLandAccess(void* data)
  469. {
  470. LLFloaterLand* self = (LLFloaterLand*)data;
  471. self->mPanelAccess = new LLPanelLandAccess(self->mParcel);
  472. return self->mPanelAccess;
  473. }
  474. //---------------------------------------------------------------------------
  475. // LLPanelLandGeneral
  476. //---------------------------------------------------------------------------
  477. LLPanelLandGeneral::LLPanelLandGeneral(LLParcelSelectionHandle& parcel)
  478. : LLPanel("land_general_panel"),
  479. mUncheckedSell(false),
  480. mParcel(parcel)
  481. {
  482. }
  483. bool LLPanelLandGeneral::postBuild()
  484. {
  485. mEditName = getChild<LLLineEditor>("name_editor");
  486. mEditName->setCommitCallback(onCommitAny);
  487. mEditName->setPrevalidate(LLLineEditor::prevalidatePrintableNotPipe);
  488. mEditName->setCallbackUserData(this);
  489. mEditDesc = getChild<LLTextEditor>("desc_editor");
  490. mEditDesc->setCommitOnFocusLost(true);
  491. mEditDesc->setCommitCallback(onCommitAny);
  492. mEditDesc->setCallbackUserData(this);
  493. #if 0 // No prevalidate function; historically the prevalidate function was
  494. // broken, allowing residents to put in characters like U+2661 WHITE
  495. // HEART SUIT, so preserve that ability.
  496. mEditDesc->setPrevalidate(LLLineEditor::prevalidatePrintableNotPipe);
  497. #endif
  498. mTextSalePending = getChild<LLTextBox>("sale_pending");
  499. mTextOwner = getChild<LLTextBox>("owner_text");
  500. mContentRating = getChild<LLTextBox>("rating_text");
  501. mLandType = getChild<LLTextBox>("land_type_text");
  502. mBtnProfile = getChild<LLButton>("profile_btn");
  503. mBtnProfile->setClickedCallback(onClickProfile, this);
  504. mTextGroup = getChild<LLTextBox>("group_text");
  505. mBtnSetGroup = getChild<LLButton>("group_btn");
  506. mBtnSetGroup->setClickedCallback(onClickSetGroup, this);
  507. mCheckDeedToGroup = getChild<LLCheckBoxCtrl>("check_deed");
  508. mCheckDeedToGroup->setCommitCallback(onCommitAny);
  509. mCheckDeedToGroup->setCallbackUserData(this);
  510. mBtnDeedToGroup = getChild<LLButton>("deed_btn");
  511. mBtnDeedToGroup->setClickedCallback(onClickDeed, this);
  512. mCheckContributeWithDeed = getChild<LLCheckBoxCtrl>("check_contrib");
  513. mCheckContributeWithDeed->setCommitCallback(onCommitAny);
  514. mCheckContributeWithDeed->setCallbackUserData(this);
  515. mSaleInfoNotForSale = getChild<LLTextBox>("not_for_sale");
  516. mSaleInfoForSale1 = getChild<LLTextBox>("sale_price");
  517. mBtnSellLand = getChild<LLButton>("sell_btn");
  518. mBtnSellLand->setClickedCallback(onClickSellLand, this);
  519. mSaleInfoForSale2 = getChild<LLTextBox>("for_sale_to");
  520. mSaleInfoForSaleObjects = getChild<LLTextBox>("sell_with_objects");
  521. mSaleInfoForSaleNoObjects = getChild<LLTextBox>("sell_without_objects");
  522. mBtnStopSellLand = getChild<LLButton>("cancel_sale_btn");
  523. mBtnStopSellLand->setClickedCallback(onClickStopSellLand, this);
  524. mTextClaimDateLabel = getChild<LLTextBox>("claimed_text");
  525. mTextClaimDate = getChild<LLTextBox>("date_claimed_text");
  526. mTextPriceLabel = getChild<LLTextBox>("price_label");
  527. mTextPrice = getChild<LLTextBox>("price_text");
  528. mTextDwell = getChild<LLTextBox>("dwell_text");
  529. mBtnBuyLand = getChild<LLButton>("buy_land_btn");
  530. mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND);
  531. mBtnBuyGroupLand = getChild<LLButton>("buy_for_group_btn");
  532. mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND);
  533. mBtnBuyPass = getChild<LLButton>("buy_pass_btn");
  534. mBtnBuyPass->setClickedCallback(onClickBuyPass, this);
  535. mBtnReleaseLand = getChild<LLButton>("abandon_btn");
  536. mBtnReleaseLand->setClickedCallback(onClickRelease, NULL);
  537. mBtnReclaimLand = getChild<LLButton>("reclaim_btn");
  538. mBtnReclaimLand->setClickedCallback(onClickReclaim, NULL);
  539. mBtnStartAuction = getChild<LLButton>("sale_btn");
  540. mBtnStartAuction->setClickedCallback(onClickStartAuction, NULL);
  541. mAnyoneText = getString("anyone");
  542. return true;
  543. }
  544. //virtual
  545. LLPanelLandGeneral::~LLPanelLandGeneral()
  546. {
  547. // Release the selection handle
  548. mParcel = NULL;
  549. }
  550. //virtual
  551. void LLPanelLandGeneral::refresh()
  552. {
  553. mBtnStartAuction->setVisible(gAgent.isGodlike());
  554. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  555. bool region_owner = false;
  556. LLViewerRegion* regionp = gViewerParcelMgr.getSelectionRegion();
  557. if (regionp && regionp->getOwner() == gAgentID)
  558. {
  559. region_owner = true;
  560. mBtnReleaseLand->setVisible(false);
  561. mBtnReclaimLand->setVisible(true);
  562. }
  563. else
  564. {
  565. mBtnReleaseLand->setVisible(true);
  566. mBtnReclaimLand->setVisible(false);
  567. }
  568. if (!parcel)
  569. {
  570. // Nothing selected, disable panel
  571. mEditName->setEnabled(false);
  572. mEditName->setText(LLStringUtil::null);
  573. mEditDesc->setEnabled(false);
  574. mEditDesc->setText(getString("no_selection_text"));
  575. mTextSalePending->setText(LLStringUtil::null);
  576. mTextSalePending->setEnabled(false);
  577. mBtnDeedToGroup->setEnabled(false);
  578. mBtnSetGroup->setEnabled(false);
  579. mBtnStartAuction->setEnabled(false);
  580. mCheckDeedToGroup->set(false);
  581. mCheckDeedToGroup->setEnabled(false);
  582. mCheckContributeWithDeed->set(false);
  583. mCheckContributeWithDeed->setEnabled(false);
  584. mTextOwner->setText(LLStringUtil::null);
  585. mContentRating->setText(LLStringUtil::null);
  586. mLandType->setText(LLStringUtil::null);
  587. mBtnProfile->setLabel(getString("profile_text"));
  588. mBtnProfile->setEnabled(false);
  589. mTextClaimDate->setText(LLStringUtil::null);
  590. mTextGroup->setText(LLStringUtil::null);
  591. mTextPrice->setText(LLStringUtil::null);
  592. mSaleInfoForSale1->setVisible(false);
  593. mSaleInfoForSale2->setVisible(false);
  594. mSaleInfoForSaleObjects->setVisible(false);
  595. mSaleInfoForSaleNoObjects->setVisible(false);
  596. mSaleInfoNotForSale->setVisible(false);
  597. mBtnSellLand->setVisible(false);
  598. mBtnStopSellLand->setVisible(false);
  599. mTextPriceLabel->setText(LLStringUtil::null);
  600. mTextDwell->setText(LLStringUtil::null);
  601. mBtnBuyLand->setEnabled(false);
  602. mBtnBuyGroupLand->setEnabled(false);
  603. mBtnReleaseLand->setEnabled(false);
  604. mBtnReclaimLand->setEnabled(false);
  605. mBtnBuyPass->setEnabled(false);
  606. return;
  607. }
  608. // Something selected, hooray !
  609. bool is_leased = parcel->getOwnershipStatus() == LLParcel::OS_LEASED;
  610. bool region_xfer = false;
  611. if (regionp && !regionp->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
  612. {
  613. region_xfer = true;
  614. }
  615. if (regionp)
  616. {
  617. mContentRating->setText(regionp->getSimAccessString());
  618. mLandType->setText(regionp->getSimProductName());
  619. }
  620. // Estate owner/manager cannot edit other parts of the parcel
  621. bool estate_manager_sellable = !parcel->getAuctionID() &&
  622. gAgent.canManageEstate() && regionp &&
  623. // Estate manager/owner can only sell
  624. // parcels owned by estate owner
  625. parcel->getOwnerID() == regionp->getOwner();
  626. bool owner_sellable = region_xfer && !parcel->getAuctionID() &&
  627. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  628. GP_LAND_SET_SALE_INFO);
  629. bool can_be_sold = owner_sellable || estate_manager_sellable;
  630. const LLUUID& owner_id = parcel->getOwnerID();
  631. bool is_public = parcel->isPublic();
  632. // Is it owned ?
  633. if (is_public)
  634. {
  635. mTextSalePending->setText(LLStringUtil::null);
  636. mTextSalePending->setEnabled(false);
  637. mTextOwner->setText(getString("public_text"));
  638. mTextOwner->setEnabled(false);
  639. mBtnProfile->setEnabled(false);
  640. mTextClaimDate->setText(LLStringUtil::null);
  641. mTextClaimDate->setEnabled(false);
  642. mTextGroup->setText(getString("none_text"));
  643. mTextGroup->setEnabled(false);
  644. mBtnStartAuction->setEnabled(false);
  645. }
  646. else
  647. {
  648. if (!is_leased && owner_id == gAgentID)
  649. {
  650. mTextSalePending->setText(getString("need_tier_to_modify"));
  651. mTextSalePending->setEnabled(true);
  652. }
  653. else if (parcel->getAuctionID())
  654. {
  655. mTextSalePending->setText(getString("auction_id_text"));
  656. mTextSalePending->setTextArg("[ID]",
  657. llformat("%u",
  658. parcel->getAuctionID()));
  659. mTextSalePending->setEnabled(true);
  660. }
  661. else
  662. {
  663. // Not the owner, or it is leased
  664. mTextSalePending->setText(LLStringUtil::null);
  665. mTextSalePending->setEnabled(false);
  666. }
  667. mTextOwner->setEnabled(true);
  668. // We support both group and personal profiles
  669. mBtnProfile->setEnabled(true);
  670. bool got_group = parcel->getGroupID().notNull();
  671. mTextGroup->setEnabled(got_group);
  672. if (!got_group)
  673. {
  674. mTextGroup->setText(getString("none_text"));
  675. }
  676. if (got_group && parcel->getIsGroupOwned())
  677. {
  678. // Group owned, so "Info"
  679. mBtnProfile->setLabel(getString("info_text"));
  680. mTextGroup->setEnabled(true);
  681. }
  682. else
  683. {
  684. // Not group owned, so "Profile"
  685. mBtnProfile->setLabel(getString("profile_text"));
  686. }
  687. std::string datestr = formatted_time(parcel->getClaimDate());
  688. mTextClaimDate->setText(datestr);
  689. mTextClaimDate->setEnabled(is_leased);
  690. bool enable_auction = gAgent.getGodLevel() >= GOD_LIAISON &&
  691. owner_id == GOVERNOR_LINDEN_ID &&
  692. parcel->getAuctionID() == 0;
  693. mBtnStartAuction->setEnabled(enable_auction);
  694. }
  695. // Display options
  696. bool can_edit_identity =
  697. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  698. GP_LAND_CHANGE_IDENTITY);
  699. mEditName->setEnabled(can_edit_identity);
  700. mEditDesc->setEnabled(can_edit_identity);
  701. bool can_edit_agent_only =
  702. LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_NO_POWERS);
  703. mBtnSetGroup->setEnabled(can_edit_agent_only &&
  704. !parcel->getIsGroupOwned());
  705. const LLUUID& group_id = parcel->getGroupID();
  706. // Can only allow deeding if you own it and it's got a group.
  707. bool enable_deed = owner_id == gAgentID && group_id.notNull() &&
  708. gAgent.isInGroup(group_id);
  709. // You do not need special powers to allow your object to be deeded to the
  710. // group.
  711. mCheckDeedToGroup->setEnabled(enable_deed);
  712. mCheckDeedToGroup->set(parcel->getAllowDeedToGroup());
  713. mCheckContributeWithDeed->setEnabled(enable_deed &&
  714. parcel->getAllowDeedToGroup());
  715. mCheckContributeWithDeed->set(parcel->getContributeWithDeed());
  716. // Actually doing the deeding requires you to have GP_LAND_DEED powers in
  717. // the group.
  718. bool can_deed = gAgent.hasPowerInGroup(group_id, GP_LAND_DEED);
  719. mBtnDeedToGroup->setEnabled(parcel->getAllowDeedToGroup() &&
  720. group_id.notNull() && can_deed &&
  721. !parcel->getIsGroupOwned());
  722. mEditName->setText(parcel->getName());
  723. mEditDesc->setText(parcel->getDesc());
  724. bool for_sale = parcel->getForSale();
  725. mBtnSellLand->setVisible(false);
  726. mBtnStopSellLand->setVisible(false);
  727. // Show pricing information
  728. S32 area, claim_price, rent_price;
  729. F32 dwell = DWELL_NAN;
  730. gViewerParcelMgr.getDisplayInfo(&area, &claim_price, &rent_price,
  731. &for_sale, &dwell);
  732. // Area
  733. LLUIString price = getString("area_size_text");
  734. price.setArg("[AREA]", llformat("%d", area));
  735. mTextPriceLabel->setText(getString("area_text"));
  736. mTextPrice->setText(price.getString());
  737. if (dwell == DWELL_NAN)
  738. {
  739. mTextDwell->setText(LLTrans::getString("LoadingData"));
  740. }
  741. else
  742. {
  743. mTextDwell->setText(llformat("%.0f", dwell));
  744. }
  745. if (for_sale)
  746. {
  747. mSaleInfoForSale1->setVisible(true);
  748. mSaleInfoForSale2->setVisible(true);
  749. if (parcel->getSellWithObjects())
  750. {
  751. mSaleInfoForSaleObjects->setVisible(true);
  752. mSaleInfoForSaleNoObjects->setVisible(false);
  753. }
  754. else
  755. {
  756. mSaleInfoForSaleObjects->setVisible(false);
  757. mSaleInfoForSaleNoObjects->setVisible(true);
  758. }
  759. mSaleInfoNotForSale->setVisible(false);
  760. F32 cost_per_sqm = 0.f;
  761. if (area > 0)
  762. {
  763. cost_per_sqm = (F32)parcel->getSalePrice() / (F32)area;
  764. }
  765. mSaleInfoForSale1->setTextArg("[PRICE]",
  766. llformat("%d", parcel->getSalePrice()));
  767. mSaleInfoForSale1->setTextArg("[PRICE_PER_SQM]",
  768. llformat("%.1f", cost_per_sqm));
  769. if (can_be_sold)
  770. {
  771. mBtnStopSellLand->setVisible(true);
  772. }
  773. }
  774. else
  775. {
  776. mSaleInfoForSale1->setVisible(false);
  777. mSaleInfoForSale2->setVisible(false);
  778. mSaleInfoForSaleObjects->setVisible(false);
  779. mSaleInfoForSaleNoObjects->setVisible(false);
  780. mSaleInfoNotForSale->setVisible(true);
  781. if (can_be_sold)
  782. {
  783. mBtnSellLand->setVisible(true);
  784. }
  785. }
  786. refreshNames();
  787. mBtnBuyLand->setEnabled(gViewerParcelMgr.canAgentBuyParcel(parcel, false));
  788. mBtnBuyGroupLand->setEnabled(gViewerParcelMgr.canAgentBuyParcel(parcel,
  789. true));
  790. if (region_owner)
  791. {
  792. mBtnReclaimLand->setEnabled(!is_public &&
  793. parcel->getOwnerID() != gAgentID);
  794. }
  795. else
  796. {
  797. bool is_owner_release =
  798. LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_RELEASE);
  799. bool is_manager_release = gAgent.canManageEstate() && regionp &&
  800. parcel->getOwnerID() != regionp->getOwner();
  801. mBtnReleaseLand->setEnabled(is_owner_release || is_manager_release);
  802. }
  803. bool use_pass = parcel->getOwnerID() != gAgentID &&
  804. parcel->getParcelFlag(PF_USE_PASS_LIST) &&
  805. !gViewerParcelMgr.isCollisionBanned();
  806. mBtnBuyPass->setEnabled(use_pass);
  807. }
  808. void LLPanelLandGeneral::refreshNames()
  809. {
  810. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  811. if (!parcel)
  812. {
  813. mTextOwner->setText(LLStringUtil::null);
  814. return;
  815. }
  816. std::string owner;
  817. if (parcel->getIsGroupOwned())
  818. {
  819. owner = getString("group_owned_text");
  820. }
  821. else if (gCacheNamep)
  822. {
  823. // Figure out the owner's name
  824. gCacheNamep->getFullName(parcel->getOwnerID(), owner);
  825. }
  826. if (parcel->getOwnershipStatus() == LLParcel::OS_LEASE_PENDING)
  827. {
  828. owner += getString("sale_pending_text");
  829. }
  830. mTextOwner->setText(owner);
  831. std::string group;
  832. if (parcel->getGroupID().notNull() && gCacheNamep)
  833. {
  834. gCacheNamep->getGroupName(parcel->getGroupID(), group);
  835. }
  836. mTextGroup->setText(group);
  837. const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
  838. if (auth_buyer_id.notNull())
  839. {
  840. std::string name;
  841. if (gCacheNamep)
  842. {
  843. gCacheNamep->getFullName(auth_buyer_id, name);
  844. }
  845. mSaleInfoForSale2->setTextArg("[BUYER]", name);
  846. }
  847. else
  848. {
  849. mSaleInfoForSale2->setTextArg("[BUYER]", mAnyoneText);
  850. }
  851. }
  852. //virtual
  853. void LLPanelLandGeneral::draw()
  854. {
  855. refreshNames();
  856. LLPanel::draw();
  857. }
  858. //static
  859. void LLPanelLandGeneral::onClickSetGroup(void* userdata)
  860. {
  861. LLPanelLandGeneral* self = (LLPanelLandGeneral*)userdata;
  862. if (!self || !gFloaterViewp) return;
  863. LLFloaterGroupPicker* fg = LLFloaterGroupPicker::show(cbGroupID, userdata);
  864. if (fg)
  865. {
  866. LLFloater* parentp = gFloaterViewp->getParentFloater(self);
  867. if (!parentp) return;
  868. LLRect new_rect = gFloaterViewp->findNeighboringPosition(parentp, fg);
  869. fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
  870. parentp->addDependentFloater(fg);
  871. }
  872. }
  873. //static
  874. void LLPanelLandGeneral::onClickProfile(void* data)
  875. {
  876. LLPanelLandGeneral* self = (LLPanelLandGeneral*)data;
  877. if (!self || !self->mParcel) return;
  878. LLParcel* parcel = self->mParcel->getParcel();
  879. if (!parcel) return;
  880. if (parcel->getIsGroupOwned())
  881. {
  882. const LLUUID& group_id = parcel->getGroupID();
  883. LLFloaterGroupInfo::showFromUUID(group_id);
  884. }
  885. else
  886. {
  887. const LLUUID& avatar_id = parcel->getOwnerID();
  888. LLFloaterAvatarInfo::showFromObject(avatar_id);
  889. }
  890. }
  891. //static
  892. void LLPanelLandGeneral::cbGroupID(LLUUID group_id, void* userdata)
  893. {
  894. LLPanelLandGeneral* self = (LLPanelLandGeneral*)userdata;
  895. self->setGroup(group_id);
  896. }
  897. void LLPanelLandGeneral::setGroup(const LLUUID& group_id)
  898. {
  899. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  900. if (!parcel) return;
  901. // Set parcel properties and send message
  902. parcel->setGroupID(group_id);
  903. #if 0
  904. parcel->setGroupName(group_name);
  905. mTextGroup->setText(group_name);
  906. #endif
  907. // Send update
  908. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  909. // Update UI
  910. refresh();
  911. }
  912. //static
  913. void LLPanelLandGeneral::onClickBuyLand(void* data)
  914. {
  915. bool* for_group = (bool*)data;
  916. //MK
  917. if (gRLenabled && gRLInterface.mContainsShowloc)
  918. {
  919. return;
  920. }
  921. //mk
  922. gViewerParcelMgr.startBuyLand(*for_group);
  923. }
  924. #if 0 // unused
  925. bool LLPanelLandGeneral::enableDeedToGroup(void* data)
  926. {
  927. LLPanelLandGeneral* self = (LLPanelLandGeneral*)data;
  928. if (!self || !self->mParcel) return false;
  929. LLParcel* parcel = self->mParcel->getParcel();
  930. return parcel && parcel->getParcelFlag(PF_ALLOW_DEED_TO_GROUP);
  931. }
  932. #endif
  933. //static
  934. void LLPanelLandGeneral::onClickDeed(void*)
  935. {
  936. gViewerParcelMgr.startDeedLandToGroup();
  937. }
  938. //static
  939. void LLPanelLandGeneral::onClickRelease(void*)
  940. {
  941. gViewerParcelMgr.startReleaseLand();
  942. }
  943. //static
  944. void LLPanelLandGeneral::onClickReclaim(void*)
  945. {
  946. gViewerParcelMgr.reclaimParcel();
  947. }
  948. //static
  949. bool LLPanelLandGeneral::enableBuyPass(void* data)
  950. {
  951. LLPanelLandGeneral* self = (LLPanelLandGeneral*)data;
  952. if (!self) return false;
  953. LLParcel* parcel =
  954. self->mParcel ? self->mParcel->getParcel()
  955. : gViewerParcelMgr.getParcelSelection()->getParcel();
  956. return parcel && parcel->getParcelFlag(PF_USE_PASS_LIST) &&
  957. !gViewerParcelMgr.isCollisionBanned();
  958. }
  959. //static
  960. void LLPanelLandGeneral::onClickBuyPass(void* data)
  961. {
  962. LLPanelLandGeneral* self = (LLPanelLandGeneral*)data;
  963. if (!self) return;
  964. LLParcel* parcel =
  965. self->mParcel ? self->mParcel->getParcel()
  966. : gViewerParcelMgr.getParcelSelection()->getParcel();
  967. if (!parcel) return;
  968. S32 pass_price = parcel->getPassPrice();
  969. std::string parcel_name = parcel->getName();
  970. F32 pass_hours = parcel->getPassHours();
  971. std::string cost, time;
  972. cost = llformat("%d", pass_price);
  973. time = llformat("%.2f", pass_hours);
  974. LLSD args;
  975. args["COST"] = cost;
  976. args["PARCEL_NAME"] = parcel_name;
  977. args["TIME"] = time;
  978. gNotifications.add("LandBuyPass", args, LLSD(), cbBuyPass);
  979. }
  980. //static
  981. void LLPanelLandGeneral::onClickStartAuction(void* data)
  982. {
  983. LLPanelLandGeneral* self = (LLPanelLandGeneral*)data;
  984. if (!self || !self->mParcel) return;
  985. LLParcel* parcelp = self->mParcel->getParcel();
  986. if (parcelp)
  987. {
  988. if (parcelp->getForSale())
  989. {
  990. gNotifications.add("CannotStartAuctionAlreadyForSale");
  991. }
  992. else
  993. {
  994. LLFloaterAuction::showInstance();
  995. }
  996. }
  997. }
  998. //static
  999. bool LLPanelLandGeneral::cbBuyPass(const LLSD& notification,
  1000. const LLSD& response)
  1001. {
  1002. if (LLNotification::getSelectedOption(notification, response) == 0)
  1003. {
  1004. // User clicked OK
  1005. gViewerParcelMgr.buyPass();
  1006. }
  1007. return false;
  1008. }
  1009. //static
  1010. void LLPanelLandGeneral::onCommitAny(LLUICtrl* ctrl, void* userdata)
  1011. {
  1012. LLPanelLandGeneral* self = (LLPanelLandGeneral*)userdata;
  1013. if (!self || !self->mParcel) return;
  1014. LLParcel* parcel = self->mParcel->getParcel();
  1015. if (!parcel)
  1016. {
  1017. return;
  1018. }
  1019. // Extract data from UI
  1020. std::string name = self->mEditName->getText();
  1021. std::string desc = self->mEditDesc->getText();
  1022. // Valid data from UI
  1023. // Stuff data into selected parcel
  1024. parcel->setName(name);
  1025. parcel->setDesc(desc);
  1026. bool allow_deed_to_group = self->mCheckDeedToGroup->get();
  1027. parcel->setParcelFlag(PF_ALLOW_DEED_TO_GROUP, allow_deed_to_group);
  1028. bool contribute_with_deed = self->mCheckContributeWithDeed->get();
  1029. parcel->setContributeWithDeed(contribute_with_deed);
  1030. // Send update to server
  1031. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  1032. // Might have changed properties, so let's redraw!
  1033. self->refresh();
  1034. }
  1035. //static
  1036. void LLPanelLandGeneral::onClickSellLand(void* data)
  1037. {
  1038. gViewerParcelMgr.startSellLand();
  1039. }
  1040. //static
  1041. void LLPanelLandGeneral::onClickStopSellLand(void* data)
  1042. {
  1043. LLPanelLandGeneral* self = (LLPanelLandGeneral*)data;
  1044. if (!self || !self->mParcel) return;
  1045. LLParcel* parcel = self->mParcel->getParcel();
  1046. parcel->setParcelFlag(PF_FOR_SALE, false);
  1047. parcel->setSalePrice(0);
  1048. parcel->setAuthorizedBuyerID(LLUUID::null);
  1049. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  1050. }
  1051. //---------------------------------------------------------------------------
  1052. // LLPanelLandObjects
  1053. //---------------------------------------------------------------------------
  1054. LLPanelLandObjects::LLPanelLandObjects(LLParcelSelectionHandle& parcel)
  1055. : LLPanel("land_objects_panel"),
  1056. mParcel(parcel)
  1057. {
  1058. }
  1059. bool LLPanelLandObjects::postBuild()
  1060. {
  1061. mFirstReply = true;
  1062. mParcelObjectBonus = getChild<LLTextBox>("parcel_object_bonus");
  1063. mSWTotalObjects = getChild<LLTextBox>("objects_available");
  1064. mObjectContribution = getChild<LLTextBox>("object_contrib_text");
  1065. mTotalObjects = getChild<LLTextBox>("total_objects_text");
  1066. mOwnerObjects = getChild<LLTextBox>("owner_objects_text");
  1067. mBtnShowOwnerObjects = getChild<LLButton>("show_owner_btn");
  1068. mBtnShowOwnerObjects->setClickedCallback(onClickShowOwnerObjects, this);
  1069. mBtnReturnOwnerObjects = getChild<LLButton>("return_owner_btn");
  1070. mBtnReturnOwnerObjects->setClickedCallback(onClickReturnOwnerObjects,
  1071. this);
  1072. mGroupObjects = getChild<LLTextBox>("group_objects_text");
  1073. mBtnShowGroupObjects = getChild<LLButton>("show_group_btn");
  1074. mBtnShowGroupObjects->setClickedCallback(onClickShowGroupObjects, this);
  1075. mBtnReturnGroupObjects = getChild<LLButton>("return_group_btn");
  1076. mBtnReturnGroupObjects->setClickedCallback(onClickReturnGroupObjects,
  1077. this);
  1078. mOtherObjects = getChild<LLTextBox>("other_objects_text");
  1079. mBtnShowOtherObjects = getChild<LLButton>("show_other_btn");
  1080. mBtnShowOtherObjects->setClickedCallback(onClickShowOtherObjects, this);
  1081. mBtnReturnOtherObjects = getChild<LLButton>("return_other_btn");
  1082. mBtnReturnOtherObjects->setClickedCallback(onClickReturnOtherObjects,
  1083. this);
  1084. mSelectedObjects = getChild<LLTextBox>("selected_objects_text");
  1085. mCleanOtherObjectsTime = getChild<LLLineEditor>("auto_return_delay");
  1086. mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus, this);
  1087. mCleanOtherObjectsTime->setCommitCallback(onCommitClean);
  1088. mCleanOtherObjectsTime->setCallbackUserData(this);
  1089. mCleanOtherObjectsTime->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
  1090. mBtnRefresh = getChild<LLButton>("refresh_btn");
  1091. mBtnRefresh->setClickedCallback(onClickRefresh, this);
  1092. mBtnReturnOwnerList = getChild<LLButton>("return_btn");
  1093. mBtnReturnOwnerList->setClickedCallback(onClickReturnOwnerList, this);
  1094. mIconAvatarOnline = LLUI::getUIImage("icon_avatar_online.tga");
  1095. mIconAvatarOffline = LLUI::getUIImage("icon_avatar_offline.tga");
  1096. mIconGroup = LLUI::getUIImage("icon_group.tga");
  1097. mOwnerList = getChild<LLNameListCtrl>("owner_list");
  1098. mOwnerList->sortByColumnIndex(3, false);
  1099. mOwnerList->setCommitCallback(onCommitList);
  1100. mOwnerList->setCallbackUserData(this);
  1101. mOwnerList->setDoubleClickCallback(onDoubleClickOwner);
  1102. return true;
  1103. }
  1104. //virtual
  1105. LLPanelLandObjects::~LLPanelLandObjects()
  1106. {
  1107. // Release the selection handle
  1108. mParcel = NULL;
  1109. }
  1110. //static
  1111. void LLPanelLandObjects::onDoubleClickOwner(void* userdata)
  1112. {
  1113. LLPanelLandObjects* self = (LLPanelLandObjects*)userdata;
  1114. LLScrollListItem* item = self->mOwnerList->getFirstSelected();
  1115. if (item)
  1116. {
  1117. LLUUID owner_id = item->getUUID();
  1118. // Look up the selected name, for future dialog box use.
  1119. const LLScrollListCell* cell = item->getColumn(1);
  1120. if (!cell)
  1121. {
  1122. return;
  1123. }
  1124. // Is this a group ?
  1125. if (cell->getValue().asString() == OWNER_GROUP)
  1126. {
  1127. // Yes, show group info
  1128. LLFloaterGroupInfo::showFromUUID(owner_id);
  1129. }
  1130. else
  1131. {
  1132. // No, show owner profile
  1133. LLFloaterAvatarInfo::showFromDirectory(owner_id);
  1134. }
  1135. }
  1136. }
  1137. //virtual
  1138. void LLPanelLandObjects::refresh()
  1139. {
  1140. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  1141. mBtnShowOwnerObjects->setEnabled(false);
  1142. mBtnShowGroupObjects->setEnabled(false);
  1143. mBtnShowOtherObjects->setEnabled(false);
  1144. mBtnReturnOwnerObjects->setEnabled(false);
  1145. mBtnReturnGroupObjects->setEnabled(false);
  1146. mBtnReturnOtherObjects->setEnabled(false);
  1147. mCleanOtherObjectsTime->setEnabled(false);
  1148. mBtnRefresh->setEnabled(false);
  1149. mBtnReturnOwnerList->setEnabled(false);
  1150. mSelectedOwners.clear();
  1151. mOwnerList->deleteAllItems();
  1152. mOwnerList->setEnabled(false);
  1153. if (!parcel)
  1154. {
  1155. mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1156. mSWTotalObjects->setTextArg("[TOTAL]", llformat("%d", 0));
  1157. mSWTotalObjects->setTextArg("[AVAILABLE]", llformat("%d", 0));
  1158. mObjectContribution->setTextArg("[COUNT]", llformat("%d", 0));
  1159. mTotalObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1160. mOwnerObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1161. mGroupObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1162. mOtherObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1163. mSelectedObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1164. }
  1165. else
  1166. {
  1167. S32 sw_max = parcel->getSimWideMaxPrimCapacity();
  1168. S32 sw_total = parcel->getSimWidePrimCount();
  1169. S32 max = ll_roundp(parcel->getMaxPrimCapacity() *
  1170. parcel->getParcelPrimBonus());
  1171. S32 total = parcel->getPrimCount();
  1172. S32 owned = parcel->getOwnerPrimCount();
  1173. S32 group = parcel->getGroupPrimCount();
  1174. S32 other = parcel->getOtherPrimCount();
  1175. S32 selected = parcel->getSelectedPrimCount();
  1176. F32 parcel_object_bonus = parcel->getParcelPrimBonus();
  1177. mOtherTime = parcel->getCleanOtherTime();
  1178. // Cannot have more than region max tasks, regardless of parcel object
  1179. // bonus factor.
  1180. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  1181. if (region)
  1182. {
  1183. S32 max_tasks_per_region = (S32)region->getMaxTasks();
  1184. sw_max = llmin(sw_max, max_tasks_per_region);
  1185. max = llmin(max, max_tasks_per_region);
  1186. }
  1187. if (parcel_object_bonus != 1.f)
  1188. {
  1189. mParcelObjectBonus->setVisible(true);
  1190. mParcelObjectBonus->setTextArg("[BONUS]",
  1191. llformat("%.2f",
  1192. parcel_object_bonus));
  1193. }
  1194. else
  1195. {
  1196. mParcelObjectBonus->setVisible(false);
  1197. }
  1198. if (sw_total > sw_max)
  1199. {
  1200. mSWTotalObjects->setText(getString("objects_deleted_text"));
  1201. mSWTotalObjects->setTextArg("[DELETED]",
  1202. llformat("%d", sw_total - sw_max));
  1203. }
  1204. else
  1205. {
  1206. mSWTotalObjects->setText(getString("objects_available_text"));
  1207. mSWTotalObjects->setTextArg("[AVAILABLE]",
  1208. llformat("%d", sw_max - sw_total));
  1209. }
  1210. mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", sw_total));
  1211. mSWTotalObjects->setTextArg("[MAX]", llformat("%d", sw_max));
  1212. mObjectContribution->setTextArg("[COUNT]", llformat("%d", max));
  1213. mTotalObjects->setTextArg("[COUNT]", llformat("%d", total));
  1214. mOwnerObjects->setTextArg("[COUNT]", llformat("%d", owned));
  1215. mGroupObjects->setTextArg("[COUNT]", llformat("%d", group));
  1216. mOtherObjects->setTextArg("[COUNT]", llformat("%d", other));
  1217. mSelectedObjects->setTextArg("[COUNT]", llformat("%d", selected));
  1218. mCleanOtherObjectsTime->setText(llformat("%d", mOtherTime));
  1219. bool can_return_owned =
  1220. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  1221. GP_LAND_RETURN_GROUP_OWNED);
  1222. bool can_return_group_set =
  1223. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  1224. GP_LAND_RETURN_GROUP_SET);
  1225. bool can_return_other =
  1226. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  1227. GP_LAND_RETURN_NON_GROUP);
  1228. if (can_return_owned || can_return_group_set || can_return_other)
  1229. {
  1230. if (owned && can_return_owned)
  1231. {
  1232. mBtnShowOwnerObjects->setEnabled(true);
  1233. mBtnReturnOwnerObjects->setEnabled(true);
  1234. }
  1235. if (group && can_return_group_set)
  1236. {
  1237. mBtnShowGroupObjects->setEnabled(true);
  1238. mBtnReturnGroupObjects->setEnabled(true);
  1239. }
  1240. if (other && can_return_other)
  1241. {
  1242. mBtnShowOtherObjects->setEnabled(true);
  1243. mBtnReturnOtherObjects->setEnabled(true);
  1244. }
  1245. mCleanOtherObjectsTime->setEnabled(true);
  1246. mBtnRefresh->setEnabled(true);
  1247. }
  1248. }
  1249. }
  1250. void send_other_clean_time_message(S32 parcel_local_id, S32 other_clean_time)
  1251. {
  1252. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  1253. if (!region) return;
  1254. LLMessageSystem* msg = gMessageSystemp;
  1255. msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime);
  1256. msg->nextBlockFast(_PREHASH_AgentData);
  1257. msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
  1258. msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
  1259. msg->nextBlockFast(_PREHASH_ParcelData);
  1260. msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
  1261. msg->addS32Fast(_PREHASH_OtherCleanTime, other_clean_time);
  1262. msg->sendReliable(region->getHost());
  1263. }
  1264. void send_return_objects_message(S32 parcel_local_id, S32 return_type,
  1265. owners_list_t* owner_ids = NULL)
  1266. {
  1267. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  1268. if (!region) return;
  1269. LLMessageSystem* msg = gMessageSystemp;
  1270. msg->newMessageFast(_PREHASH_ParcelReturnObjects);
  1271. msg->nextBlockFast(_PREHASH_AgentData);
  1272. msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
  1273. msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
  1274. msg->nextBlockFast(_PREHASH_ParcelData);
  1275. msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
  1276. msg->addU32Fast(_PREHASH_ReturnType, (U32) return_type);
  1277. // Dummy task id, not used
  1278. msg->nextBlock("TaskIDs");
  1279. msg->addUUID("TaskID", LLUUID::null);
  1280. // Throw all return ids into the packet. *TODO: Check for too many Ids.
  1281. if (owner_ids)
  1282. {
  1283. for (owners_list_t::iterator it = owner_ids->begin(),
  1284. end = owner_ids->end();
  1285. it != end; ++it)
  1286. {
  1287. msg->nextBlockFast(_PREHASH_OwnerIDs);
  1288. msg->addUUIDFast(_PREHASH_OwnerID, (*it));
  1289. }
  1290. }
  1291. else
  1292. {
  1293. msg->nextBlockFast(_PREHASH_OwnerIDs);
  1294. msg->addUUIDFast(_PREHASH_OwnerID, LLUUID::null);
  1295. }
  1296. msg->sendReliable(region->getHost());
  1297. }
  1298. bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification,
  1299. const LLSD& response)
  1300. {
  1301. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  1302. if (parcel &&
  1303. LLNotification::getSelectedOption(notification, response) == 0)
  1304. {
  1305. LLUUID owner_id = parcel->getOwnerID();
  1306. LLSD args;
  1307. if (owner_id == gAgentID)
  1308. {
  1309. gNotifications.add("OwnedObjectsReturned");
  1310. }
  1311. else
  1312. {
  1313. std::string name;
  1314. if (gCacheNamep)
  1315. {
  1316. gCacheNamep->getFullName(owner_id, name);
  1317. }
  1318. args["NAME"] = name;
  1319. gNotifications.add("OtherObjectsReturned", args);
  1320. }
  1321. send_return_objects_message(parcel->getLocalID(), RT_OWNER);
  1322. }
  1323. gSelectMgr.unhighlightAll();
  1324. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  1325. refresh();
  1326. return false;
  1327. }
  1328. bool LLPanelLandObjects::callbackReturnGroupObjects(const LLSD& notification,
  1329. const LLSD& response)
  1330. {
  1331. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  1332. if (parcel &&
  1333. LLNotification::getSelectedOption(notification, response) == 0)
  1334. {
  1335. std::string group_name;
  1336. if (gCacheNamep)
  1337. {
  1338. gCacheNamep->getGroupName(parcel->getGroupID(), group_name);
  1339. }
  1340. LLSD args;
  1341. args["GROUPNAME"] = group_name;
  1342. gNotifications.add("GroupObjectsReturned", args);
  1343. send_return_objects_message(parcel->getLocalID(), RT_GROUP);
  1344. }
  1345. gSelectMgr.unhighlightAll();
  1346. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  1347. refresh();
  1348. return false;
  1349. }
  1350. bool LLPanelLandObjects::callbackReturnOtherObjects(const LLSD& notification,
  1351. const LLSD& response)
  1352. {
  1353. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  1354. if (parcel &&
  1355. LLNotification::getSelectedOption(notification, response) == 0)
  1356. {
  1357. gNotifications.add("UnOwnedObjectsReturned");
  1358. send_return_objects_message(parcel->getLocalID(), RT_OTHER);
  1359. }
  1360. gSelectMgr.unhighlightAll();
  1361. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  1362. refresh();
  1363. return false;
  1364. }
  1365. bool LLPanelLandObjects::callbackReturnOwnerList(const LLSD& notification,
  1366. const LLSD& response)
  1367. {
  1368. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  1369. if (parcel &&
  1370. LLNotification::getSelectedOption(notification, response) == 0)
  1371. {
  1372. // Make sure we have something selected.
  1373. owners_list_t::iterator selected = mSelectedOwners.begin();
  1374. if (selected != mSelectedOwners.end())
  1375. {
  1376. LLSD args;
  1377. if (mSelectedIsGroup)
  1378. {
  1379. args["GROUPNAME"] = mSelectedName;
  1380. gNotifications.add("GroupObjectsReturned", args);
  1381. }
  1382. else
  1383. {
  1384. args["NAME"] =
  1385. LLAvatarName::sOmitResidentAsLastName ? LLCacheName::cleanFullName(mSelectedName)
  1386. : mSelectedName;
  1387. gNotifications.add("OtherObjectsReturned2", args);
  1388. }
  1389. send_return_objects_message(parcel->getLocalID(), RT_LIST,
  1390. &(mSelectedOwners));
  1391. }
  1392. }
  1393. gSelectMgr.unhighlightAll();
  1394. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  1395. refresh();
  1396. return false;
  1397. }
  1398. //static
  1399. void LLPanelLandObjects::onClickReturnOwnerList(void* userdata)
  1400. {
  1401. LLPanelLandObjects* self = (LLPanelLandObjects*)userdata;
  1402. if (!self || !self->mParcel) return;
  1403. LLParcel* parcelp = self->mParcel->getParcel();
  1404. if (!parcelp) return;
  1405. // Make sure we have something selected.
  1406. if (self->mSelectedOwners.empty())
  1407. {
  1408. return;
  1409. }
  1410. #if 0
  1411. owners_list_t::iterator it = self->mSelectedOwners.begin();
  1412. if (it == self->mSelectedOwners.end()) return;
  1413. #endif
  1414. send_parcel_select_objects(parcelp->getLocalID(), RT_LIST,
  1415. &(self->mSelectedOwners));
  1416. LLSD args;
  1417. args["NAME"] = self->mSelectedName;
  1418. args["N"] = llformat("%d",self->mSelectedCount);
  1419. if (self->mSelectedIsGroup)
  1420. {
  1421. gNotifications.add("ReturnObjectsDeededToGroup", args, LLSD(),
  1422. boost::bind(&LLPanelLandObjects::callbackReturnOwnerList,
  1423. self, _1, _2));
  1424. }
  1425. else
  1426. {
  1427. gNotifications.add("ReturnObjectsOwnedByUser", args, LLSD(),
  1428. boost::bind(&LLPanelLandObjects::callbackReturnOwnerList,
  1429. self, _1, _2));
  1430. }
  1431. }
  1432. //static
  1433. void LLPanelLandObjects::onClickRefresh(void* userdata)
  1434. {
  1435. LLPanelLandObjects* self = (LLPanelLandObjects*)userdata;
  1436. if (!self || !self->mParcel) return;
  1437. LLParcel* parcel = self->mParcel->getParcel();
  1438. if (!parcel) return;
  1439. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  1440. if (!region) return;
  1441. // Ready the list for results
  1442. self->mOwnerList->deleteAllItems();
  1443. self->mOwnerList->addCommentText("Searching..."); // *TODO: Translate
  1444. self->mOwnerList->setEnabled(false);
  1445. self->mFirstReply = true;
  1446. // Send the message
  1447. LLMessageSystem* msg = gMessageSystemp;
  1448. msg->newMessageFast(_PREHASH_ParcelObjectOwnersRequest);
  1449. msg->nextBlockFast(_PREHASH_AgentData);
  1450. msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
  1451. msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
  1452. msg->nextBlockFast(_PREHASH_ParcelData);
  1453. msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID());
  1454. msg->sendReliable(region->getHost());
  1455. }
  1456. //static
  1457. void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem* msg,
  1458. void**)
  1459. {
  1460. LLPanelLandObjects* self = LLFloaterLand::getCurrentPanelLandObjects();
  1461. if (!self)
  1462. {
  1463. llwarns << "Received message for nonexistent LLPanelLandObject"
  1464. << llendl;
  1465. return;
  1466. }
  1467. static const LLFontGL* FONT = LLFontGL::getFontSansSerif();
  1468. // Extract all of the owners.
  1469. S32 rows = msg->getNumberOfBlocksFast(_PREHASH_Data);
  1470. LLUUID owner_id;
  1471. bool is_group_owned;
  1472. S32 object_count;
  1473. U32 most_recent_time = 0;
  1474. bool is_online;
  1475. std::string object_count_str;
  1476. // If we were waiting for the first reply, clear the "Searching..." text.
  1477. if (self->mFirstReply)
  1478. {
  1479. self->mOwnerList->deleteAllItems();
  1480. self->mFirstReply = false;
  1481. }
  1482. for (S32 i = 0; i < rows; ++i)
  1483. {
  1484. msg->getUUIDFast(_PREHASH_Data, _PREHASH_OwnerID, owner_id, i);
  1485. msg->getBoolFast(_PREHASH_Data, _PREHASH_IsGroupOwned,
  1486. is_group_owned, i);
  1487. msg->getS32Fast(_PREHASH_Data, _PREHASH_Count, object_count, i);
  1488. msg->getBoolFast(_PREHASH_Data, _PREHASH_OnlineStatus, is_online, i);
  1489. if (msg->has("DataExtended"))
  1490. {
  1491. msg->getU32("DataExtended", "TimeStamp", most_recent_time, i);
  1492. }
  1493. if (owner_id.isNull())
  1494. {
  1495. continue;
  1496. }
  1497. LLScrollListItem* row = new LLScrollListItem(true, NULL, owner_id);
  1498. if (is_group_owned)
  1499. {
  1500. row->addColumn(self->mIconGroup);
  1501. row->addColumn(OWNER_GROUP, FONT);
  1502. }
  1503. else if (is_online)
  1504. {
  1505. row->addColumn(self->mIconAvatarOnline);
  1506. row->addColumn(OWNER_ONLINE, FONT);
  1507. }
  1508. else // Offline
  1509. {
  1510. row->addColumn(self->mIconAvatarOffline);
  1511. row->addColumn(OWNER_OFFLINE, FONT);
  1512. }
  1513. // Placeholder for name.
  1514. row->addColumn(LLStringUtil::null, FONT);
  1515. object_count_str = llformat("%d", object_count);
  1516. row->addColumn(object_count_str, FONT);
  1517. row->addColumn(formatted_time((time_t)most_recent_time), FONT);
  1518. if (is_group_owned)
  1519. {
  1520. self->mOwnerList->addGroupNameItem(row, ADD_BOTTOM);
  1521. }
  1522. else
  1523. {
  1524. self->mOwnerList->addNameItem(row, ADD_BOTTOM);
  1525. }
  1526. LL_DEBUGS("ParcelObject") << "Object owner " << owner_id << " ("
  1527. << (is_group_owned ? "group" : "agent")
  1528. << ") owns " << object_count << " objects."
  1529. << LL_ENDL;
  1530. }
  1531. // Check for no results
  1532. if (self->mOwnerList->getItemCount() == 0)
  1533. {
  1534. // *TODO: translate
  1535. self->mOwnerList->addCommentText("None found.");
  1536. }
  1537. else
  1538. {
  1539. self->mOwnerList->setEnabled(true);
  1540. }
  1541. }
  1542. //static
  1543. void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data)
  1544. {
  1545. LLPanelLandObjects* self = (LLPanelLandObjects*)data;
  1546. if (!self || !self->mOwnerList->getCanSelect())
  1547. {
  1548. return;
  1549. }
  1550. LLScrollListItem* item = self->mOwnerList->getFirstSelected();
  1551. if (item)
  1552. {
  1553. // Look up the selected name, for future dialog box use.
  1554. const LLScrollListCell* cell = item->getColumn(1);
  1555. if (!cell)
  1556. {
  1557. return;
  1558. }
  1559. // Is this a group ?
  1560. self->mSelectedIsGroup = cell->getValue().asString() == OWNER_GROUP;
  1561. cell = item->getColumn(2);
  1562. self->mSelectedName = cell->getValue().asString();
  1563. cell = item->getColumn(3);
  1564. self->mSelectedCount = atoi(cell->getValue().asString().c_str());
  1565. // Set the selection, and enable the return button.
  1566. self->mSelectedOwners.clear();
  1567. self->mSelectedOwners.insert(item->getUUID());
  1568. self->mBtnReturnOwnerList->setEnabled(true);
  1569. // Highlight this user's objects
  1570. clickShowCore(self, RT_LIST, &(self->mSelectedOwners));
  1571. }
  1572. }
  1573. //static
  1574. void LLPanelLandObjects::clickShowCore(LLPanelLandObjects* self,
  1575. S32 return_type,
  1576. owners_list_t* list)
  1577. {
  1578. if (!self || !self->mParcel) return;
  1579. LLParcel* parcel = self->mParcel->getParcel();
  1580. if (!parcel) return;
  1581. send_parcel_select_objects(parcel->getLocalID(), return_type, list);
  1582. }
  1583. //static
  1584. void LLPanelLandObjects::onClickShowOwnerObjects(void* userdata)
  1585. {
  1586. clickShowCore((LLPanelLandObjects*)userdata, RT_OWNER);
  1587. }
  1588. //static
  1589. void LLPanelLandObjects::onClickShowGroupObjects(void* userdata)
  1590. {
  1591. clickShowCore((LLPanelLandObjects*)userdata, (RT_GROUP));
  1592. }
  1593. //static
  1594. void LLPanelLandObjects::onClickShowOtherObjects(void* userdata)
  1595. {
  1596. clickShowCore((LLPanelLandObjects*)userdata, RT_OTHER);
  1597. }
  1598. //static
  1599. void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata)
  1600. {
  1601. LLPanelLandObjects* self = (LLPanelLandObjects*)userdata;
  1602. if (!self || !self->mParcel) return;
  1603. LLParcel* parcel = self->mParcel->getParcel();
  1604. if (!parcel) return;
  1605. send_parcel_select_objects(parcel->getLocalID(), RT_OWNER);
  1606. LLSD args;
  1607. args["N"] = llformat("%d", parcel->getOwnerPrimCount());
  1608. const LLUUID& owner_id = parcel->getOwnerID();
  1609. if (owner_id == gAgentID)
  1610. {
  1611. gNotifications.add("ReturnObjectsOwnedBySelf", args, LLSD(),
  1612. boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects,
  1613. self, _1, _2));
  1614. }
  1615. else
  1616. {
  1617. std::string name;
  1618. if (gCacheNamep)
  1619. {
  1620. gCacheNamep->getFullName(owner_id, name);
  1621. }
  1622. args["NAME"] = name;
  1623. gNotifications.add("ReturnObjectsOwnedByUser", args, LLSD(),
  1624. boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects,
  1625. self, _1, _2));
  1626. }
  1627. }
  1628. //static
  1629. void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata)
  1630. {
  1631. LLPanelLandObjects* self = (LLPanelLandObjects*)userdata;
  1632. if (!self || !self->mParcel) return;
  1633. LLParcel* parcel = self->mParcel->getParcel();
  1634. if (!parcel) return;
  1635. send_parcel_select_objects(parcel->getLocalID(), RT_GROUP);
  1636. std::string group_name;
  1637. if (gCacheNamep)
  1638. {
  1639. gCacheNamep->getGroupName(parcel->getGroupID(), group_name);
  1640. }
  1641. LLSD args;
  1642. args["NAME"] = group_name;
  1643. args["N"] = llformat("%d", parcel->getGroupPrimCount());
  1644. // Create and show confirmation text box
  1645. gNotifications.add("ReturnObjectsDeededToGroup", args, LLSD(),
  1646. boost::bind(&LLPanelLandObjects::callbackReturnGroupObjects,
  1647. self, _1, _2));
  1648. }
  1649. //static
  1650. void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)
  1651. {
  1652. LLPanelLandObjects* self = (LLPanelLandObjects*)userdata;
  1653. if (!self || !self->mParcel) return;
  1654. LLParcel* parcel = self->mParcel->getParcel();
  1655. if (!parcel) return;
  1656. send_parcel_select_objects(parcel->getLocalID(), RT_OTHER);
  1657. LLSD args;
  1658. args["N"] = llformat("%d", parcel->getOtherPrimCount());
  1659. if (parcel->getIsGroupOwned())
  1660. {
  1661. std::string group_name;
  1662. if (gCacheNamep)
  1663. {
  1664. gCacheNamep->getGroupName(parcel->getGroupID(), group_name);
  1665. }
  1666. args["NAME"] = group_name;
  1667. gNotifications.add("ReturnObjectsNotOwnedByGroup", args, LLSD(),
  1668. boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects,
  1669. self, _1, _2));
  1670. return;
  1671. }
  1672. const LLUUID& owner_id = parcel->getOwnerID();
  1673. if (owner_id == gAgentID)
  1674. {
  1675. gNotifications.add("ReturnObjectsNotOwnedBySelf", args, LLSD(),
  1676. boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects,
  1677. self, _1, _2));
  1678. return;
  1679. }
  1680. std::string name;
  1681. if (gCacheNamep)
  1682. {
  1683. gCacheNamep->getFullName(owner_id, name);
  1684. }
  1685. args["NAME"] = name;
  1686. gNotifications.add("ReturnObjectsNotOwnedByUser", args, LLSD(),
  1687. boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects,
  1688. self, _1, _2));
  1689. }
  1690. //static
  1691. void LLPanelLandObjects::onLostFocus(LLFocusableElement* caller, void* user_data)
  1692. {
  1693. onCommitClean((LLUICtrl*)caller, user_data);
  1694. }
  1695. //static
  1696. void LLPanelLandObjects::onCommitClean(LLUICtrl* caller, void* user_data)
  1697. {
  1698. LLPanelLandObjects* self = (LLPanelLandObjects*)user_data;
  1699. if (!self || !self->mParcel) return;
  1700. LLParcel* parcel = self->mParcel->getParcel();
  1701. if (parcel)
  1702. {
  1703. self->mOtherTime = atoi(self->mCleanOtherObjectsTime->getText().c_str());
  1704. parcel->setCleanOtherTime(self->mOtherTime);
  1705. send_other_clean_time_message(parcel->getLocalID(), self->mOtherTime);
  1706. }
  1707. }
  1708. //---------------------------------------------------------------------------
  1709. // LLPanelLandOptions
  1710. //---------------------------------------------------------------------------
  1711. LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
  1712. : LLPanel("land_options_panel"),
  1713. mParcel(parcel)
  1714. {
  1715. }
  1716. bool LLPanelLandOptions::postBuild()
  1717. {
  1718. mCreateObjectsCheck = getChild<LLCheckBoxCtrl>("create_obj_check");
  1719. mCreateObjectsCheck->setCommitCallback(onCommitAny);
  1720. mCreateObjectsCheck->setCallbackUserData(this);
  1721. mCreateGrpObjectsCheck = getChild<LLCheckBoxCtrl>("edit_grp_obj_check");
  1722. mCreateGrpObjectsCheck->setCommitCallback(onCommitAny);
  1723. mCreateGrpObjectsCheck->setCallbackUserData(this);
  1724. mAllObjectEntryCheck = getChild<LLCheckBoxCtrl>("all_entry_check");
  1725. mAllObjectEntryCheck->setCommitCallback(onCommitAny);
  1726. mAllObjectEntryCheck->setCallbackUserData(this);
  1727. mGroupObjectEntryCheck = getChild<LLCheckBoxCtrl>("group_entry_check");
  1728. mGroupObjectEntryCheck->setCommitCallback(onCommitAny);
  1729. mGroupObjectEntryCheck->setCallbackUserData(this);
  1730. mEditLandCheck = getChild<LLCheckBoxCtrl>("edit_land_check");
  1731. mEditLandCheck->setCommitCallback(onCommitAny);
  1732. mEditLandCheck->setCallbackUserData(this);
  1733. mAllScriptsCheck = getChild<LLCheckBoxCtrl>("allow_scripts_check");
  1734. mAllScriptsCheck->setCommitCallback(onCommitAny);
  1735. mAllScriptsCheck->setCallbackUserData(this);
  1736. mGroupScriptsCheck = getChild<LLCheckBoxCtrl>("group_scripts_check");
  1737. mGroupScriptsCheck->setCommitCallback(onCommitAny);
  1738. mGroupScriptsCheck->setCallbackUserData(this);
  1739. mCanFlyCheck = getChild<LLCheckBoxCtrl>("fly_check");
  1740. mCanFlyCheck->setCommitCallback(onCommitAny);
  1741. mCanFlyCheck->setCallbackUserData(this);
  1742. mNoDamageCheck = getChild<LLCheckBoxCtrl>("no_damage_check");
  1743. mNoDamageCheck->setCommitCallback(onCommitAny);
  1744. mNoDamageCheck->setCallbackUserData(this);
  1745. mPushRestrictionCheck = getChild<LLCheckBoxCtrl>("restrict_push_check");
  1746. mPushRestrictionCheck->setCommitCallback(onCommitAny);
  1747. mPushRestrictionCheck->setCallbackUserData(this);
  1748. mShowDirectoryCheck = getChild<LLCheckBoxCtrl>("show_directory_check");
  1749. mShowDirectoryCheck->setCommitCallback(onCommitAny);
  1750. mShowDirectoryCheck->setCallbackUserData(this);
  1751. mCategoryCombo = getChild<LLComboBox>("land_category_combo");
  1752. mCategoryCombo->setCommitCallback(onCommitAny);
  1753. mCategoryCombo->setCallbackUserData(this);
  1754. mCategoryCombo->setVisible(true);
  1755. mCategoryCombo->setEnabled(true);
  1756. mPublishHelpButton = getChild<LLButton>("help_btn");
  1757. mPublishHelpButton->setClickedCallback(onClickPublishHelp, this);
  1758. mMatureCheck = getChild<LLCheckBoxCtrl>("mature_check");
  1759. mMatureCheck->setCommitCallback(onCommitAny);
  1760. mMatureCheck->setCallbackUserData(this);
  1761. mPrivacyCheck = getChild<LLCheckBoxCtrl>("privacy_check");
  1762. mPrivacyCheck->setCommitCallback(onCommitAny);
  1763. mPrivacyCheck->setCallbackUserData(this);
  1764. if (gAgent.wantsPGOnly())
  1765. {
  1766. // Disable these buttons if they are PG (Teen) users
  1767. mPublishHelpButton->setVisible(false);
  1768. mPublishHelpButton->setEnabled(false);
  1769. mMatureCheck->setVisible(false);
  1770. mMatureCheck->setEnabled(false);
  1771. }
  1772. mSnapshotCtrl = getChild<LLTextureCtrl>("snapshot_ctrl");
  1773. mSnapshotCtrl->setCommitCallback(onCommitAny);
  1774. mSnapshotCtrl->setCallbackUserData(this);
  1775. mSnapshotCtrl->setAllowNoTexture(true);
  1776. mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
  1777. mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
  1778. mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
  1779. mLocationText = getChild<LLTextBox>("landing_point");
  1780. mSetBtn = getChild<LLButton>("set_landing_btn");
  1781. mSetBtn->setClickedCallback(onClickSet, this);
  1782. mClearBtn = getChild<LLButton>("clear_landing_btn");
  1783. mClearBtn->setClickedCallback(onClickClear, this);
  1784. mTeleportRoutingCombo = getChild<LLComboBox>("teleport_routing_combo");
  1785. mTeleportRoutingCombo->setCommitCallback(onCommitAny);
  1786. mTeleportRoutingCombo->setCallbackUserData(this);
  1787. return true;
  1788. }
  1789. //virtual
  1790. LLPanelLandOptions::~LLPanelLandOptions()
  1791. {
  1792. // Release the selection handle
  1793. mParcel = NULL;
  1794. }
  1795. //virtual
  1796. void LLPanelLandOptions::refresh()
  1797. {
  1798. refreshSearch();
  1799. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  1800. if (!parcel)
  1801. {
  1802. mCreateObjectsCheck->set(false);
  1803. mCreateObjectsCheck->setEnabled(false);
  1804. mCreateGrpObjectsCheck->set(false);
  1805. mCreateGrpObjectsCheck->setEnabled(false);
  1806. mAllObjectEntryCheck->set(false);
  1807. mAllObjectEntryCheck->setEnabled(false);
  1808. mGroupObjectEntryCheck->set(false);
  1809. mGroupObjectEntryCheck->setEnabled(false);
  1810. mEditLandCheck->set(false);
  1811. mEditLandCheck->setEnabled(false);
  1812. mNoDamageCheck->set(false);
  1813. mNoDamageCheck->setEnabled(false);
  1814. mCanFlyCheck->set(false);
  1815. mCanFlyCheck->setEnabled(false);
  1816. mGroupScriptsCheck->set(false);
  1817. mGroupScriptsCheck->setEnabled(false);
  1818. mAllScriptsCheck->set(false);
  1819. mAllScriptsCheck->setEnabled(false);
  1820. mPushRestrictionCheck->set(false);
  1821. mPushRestrictionCheck->setEnabled(false);
  1822. mPrivacyCheck->set(true);
  1823. mPrivacyCheck->setEnabled(false);
  1824. mTeleportRoutingCombo->setCurrentByIndex(0);
  1825. mTeleportRoutingCombo->setEnabled(false);
  1826. mSnapshotCtrl->setImageAssetID(LLUUID::null);
  1827. mSnapshotCtrl->setEnabled(false);
  1828. mLocationText->setTextArg("[LANDING]",
  1829. getString("landing_point_none"));
  1830. mSetBtn->setEnabled(false);
  1831. mClearBtn->setEnabled(false);
  1832. mMatureCheck->setEnabled(false);
  1833. mPublishHelpButton->setEnabled(false);
  1834. return;
  1835. }
  1836. // Display options
  1837. bool can_change_options =
  1838. LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_OPTIONS);
  1839. mCreateObjectsCheck->set(parcel->getAllowModify());
  1840. mCreateObjectsCheck->setEnabled(can_change_options);
  1841. mCreateGrpObjectsCheck->set(parcel->getAllowGroupModify() ||
  1842. parcel->getAllowModify());
  1843. // If others edit is enabled, then this is explicitly enabled:
  1844. mCreateGrpObjectsCheck->setEnabled(can_change_options &&
  1845. !parcel->getAllowModify());
  1846. mAllObjectEntryCheck->set(parcel->getAllowAllObjectEntry());
  1847. mAllObjectEntryCheck->setEnabled(can_change_options);
  1848. mGroupObjectEntryCheck->set(parcel->getAllowGroupObjectEntry() ||
  1849. parcel->getAllowAllObjectEntry());
  1850. mGroupObjectEntryCheck->setEnabled(can_change_options &&
  1851. !parcel->getAllowAllObjectEntry());
  1852. mEditLandCheck->set(parcel->getAllowTerraform());
  1853. mEditLandCheck->setEnabled(LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  1854. GP_LAND_EDIT));
  1855. mNoDamageCheck->set(!parcel->getAllowDamage());
  1856. mNoDamageCheck->setEnabled(can_change_options);
  1857. mCanFlyCheck->set(parcel->getAllowFly());
  1858. mCanFlyCheck->setEnabled(can_change_options);
  1859. mGroupScriptsCheck->set(parcel->getAllowGroupScripts() ||
  1860. parcel->getAllowOtherScripts());
  1861. mGroupScriptsCheck->setEnabled(can_change_options &&
  1862. !parcel->getAllowOtherScripts());
  1863. mAllScriptsCheck->set(parcel->getAllowOtherScripts());
  1864. mAllScriptsCheck->setEnabled(can_change_options);
  1865. mPushRestrictionCheck->set(parcel->getRestrictPushObject());
  1866. if (parcel->getRegionPushOverride())
  1867. {
  1868. mPushRestrictionCheck->setLabel(getString("push_restrict_region_text"));
  1869. mPushRestrictionCheck->setEnabled(false);
  1870. mPushRestrictionCheck->set(true);
  1871. }
  1872. else
  1873. {
  1874. mPushRestrictionCheck->setLabel(getString("push_restrict_text"));
  1875. mPushRestrictionCheck->setEnabled(can_change_options);
  1876. }
  1877. mPrivacyCheck->set(parcel->getSeeAVs() ||
  1878. !parcel->getHaveNewParcelLimitData());
  1879. mPrivacyCheck->setEnabled(can_change_options &&
  1880. parcel->getHaveNewParcelLimitData());
  1881. bool can_change_landing =
  1882. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  1883. GP_LAND_SET_LANDING_POINT);
  1884. mTeleportRoutingCombo->setCurrentByIndex((S32)parcel->getLandingType());
  1885. mTeleportRoutingCombo->setEnabled(can_change_landing);
  1886. bool can_change_identity =
  1887. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  1888. GP_LAND_CHANGE_IDENTITY);
  1889. mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID());
  1890. mSnapshotCtrl->setEnabled(can_change_identity);
  1891. LLVector3 pos = parcel->getUserLocation();
  1892. if (pos.isExactlyZero())
  1893. {
  1894. mLocationText->setTextArg("[LANDING]",
  1895. getString("landing_point_none"));
  1896. }
  1897. else
  1898. {
  1899. mLocationText->setTextArg("[LANDING]",
  1900. llformat("%d, %d, %d",
  1901. ll_roundp(pos.mV[VX]),
  1902. ll_roundp(pos.mV[VY]),
  1903. ll_roundp(pos.mV[VZ])));
  1904. }
  1905. mSetBtn->setEnabled(can_change_landing);
  1906. mClearBtn->setEnabled(can_change_landing);
  1907. mPublishHelpButton->setEnabled(can_change_identity);
  1908. if (gAgent.wantsPGOnly())
  1909. {
  1910. // Disable these buttons if they are PG (Teen) users
  1911. mPublishHelpButton->setVisible(false);
  1912. mPublishHelpButton->setEnabled(false);
  1913. mMatureCheck->setVisible(false);
  1914. mMatureCheck->setEnabled(false);
  1915. return;
  1916. }
  1917. // Not teen so fill in the data for the maturity control
  1918. mMatureCheck->setVisible(true);
  1919. mMatureCheck->setLabel(getString("mature_check_mature"));
  1920. mMatureCheck->setToolTip(getString("mature_check_mature_tooltip"));
  1921. // They can see the checkbox, but its disposition depends on the state of
  1922. // the region
  1923. LLViewerRegion* regionp = gViewerParcelMgr.getSelectionRegion();
  1924. if (regionp)
  1925. {
  1926. U8 access = regionp->getSimAccess();
  1927. if (access == SIM_ACCESS_PG)
  1928. {
  1929. mMatureCheck->setEnabled(false);
  1930. mMatureCheck->set(false);
  1931. }
  1932. else if (access == SIM_ACCESS_MATURE)
  1933. {
  1934. mMatureCheck->setEnabled(can_change_identity);
  1935. mMatureCheck->set(parcel->getMaturePublish());
  1936. }
  1937. else if (access == SIM_ACCESS_ADULT)
  1938. {
  1939. mMatureCheck->setEnabled(false);
  1940. mMatureCheck->set(true);
  1941. mMatureCheck->setLabel(getString("mature_check_adult"));
  1942. mMatureCheck->setToolTip(getString("mature_check_adult_tooltip"));
  1943. }
  1944. }
  1945. }
  1946. //virtual
  1947. void LLPanelLandOptions::draw()
  1948. {
  1949. static F32 last_update = 0.f;
  1950. if (gFrameTimeSeconds - last_update > 2.f) // One update every 2 seconds
  1951. {
  1952. refreshSearch(); // Is this necessary ? JC
  1953. last_update = gFrameTimeSeconds;
  1954. }
  1955. LLPanel::draw();
  1956. }
  1957. void LLPanelLandOptions::refreshSearch()
  1958. {
  1959. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  1960. if (!parcel)
  1961. {
  1962. mShowDirectoryCheck->set(false);
  1963. mShowDirectoryCheck->setEnabled(false);
  1964. // *TODO:Translate
  1965. const std::string& none_string =
  1966. LLParcel::getCategoryUIString(LLParcel::C_NONE);
  1967. mCategoryCombo->setSimple(none_string);
  1968. mCategoryCombo->setEnabled(false);
  1969. return;
  1970. }
  1971. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  1972. bool can_change =
  1973. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  1974. GP_LAND_FIND_PLACES) &&
  1975. region && !region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH);
  1976. bool show_directory = parcel->getParcelFlag(PF_SHOW_DIRECTORY);
  1977. mShowDirectoryCheck->set(show_directory);
  1978. // Set by string in case the order in UI doesn't match the order by index.
  1979. // *TODO:Translate
  1980. LLParcel::ECategory cat = parcel->getCategory();
  1981. const std::string& category_string = LLParcel::getCategoryUIString(cat);
  1982. mCategoryCombo->setSimple(category_string);
  1983. std::string tooltip;
  1984. bool enable_show_directory = false;
  1985. // Parcels <= 128 square meters cannot be listed in search, in an effort to
  1986. // reduce search spam from small parcels. JC
  1987. constexpr S32 MIN_PARCEL_AREA_FOR_SEARCH = 128;
  1988. bool large_enough = parcel->getArea() > MIN_PARCEL_AREA_FOR_SEARCH;
  1989. if (large_enough)
  1990. {
  1991. if (can_change)
  1992. {
  1993. tooltip = getString("search_enabled_tooltip");
  1994. enable_show_directory = true;
  1995. }
  1996. else
  1997. {
  1998. tooltip = getString("search_disabled_permissions_tooltip");
  1999. enable_show_directory = false;
  2000. }
  2001. }
  2002. // Not large enough to include in search
  2003. else if (can_change)
  2004. {
  2005. if (show_directory)
  2006. {
  2007. // Parcels that are too small, but are still in search for
  2008. // legacy reasons, need to have the check box enabled so the
  2009. // owner can delist the parcel. JC
  2010. tooltip = getString("search_enabled_tooltip");
  2011. enable_show_directory = true;
  2012. }
  2013. else
  2014. {
  2015. tooltip = getString("search_disabled_small_tooltip");
  2016. enable_show_directory = false;
  2017. }
  2018. }
  2019. else
  2020. {
  2021. // JC - Both too small and do not have permission, so just show the
  2022. // permissions as the reason (which is probably the more common case).
  2023. tooltip = getString("search_disabled_permissions_tooltip");
  2024. enable_show_directory = false;
  2025. }
  2026. mShowDirectoryCheck->setToolTip(tooltip);
  2027. mCategoryCombo->setToolTip(tooltip);
  2028. mShowDirectoryCheck->setEnabled(enable_show_directory);
  2029. mCategoryCombo->setEnabled(enable_show_directory);
  2030. }
  2031. //static
  2032. void LLPanelLandOptions::onCommitAny(LLUICtrl* ctrl, void* userdata)
  2033. {
  2034. LLPanelLandOptions* self = (LLPanelLandOptions*)userdata;
  2035. if (!self || !self->mParcel) return;
  2036. LLParcel* parcel = self->mParcel->getParcel();
  2037. if (!parcel)
  2038. {
  2039. return;
  2040. }
  2041. // Extract data from UI
  2042. bool create_objects = self->mCreateObjectsCheck->get();
  2043. bool create_group_objects = self->mCreateGrpObjectsCheck->get() ||
  2044. self->mCreateObjectsCheck->get();
  2045. bool all_object_entry = self->mAllObjectEntryCheck->get();
  2046. bool group_object_entry = self->mGroupObjectEntryCheck->get() ||
  2047. self->mAllObjectEntryCheck->get();
  2048. bool allow_terraform = self->mEditLandCheck->get();
  2049. bool allow_damage = !self->mNoDamageCheck->get();
  2050. bool allow_fly = self->mCanFlyCheck->get();
  2051. bool allow_group_scripts = self->mGroupScriptsCheck->get() ||
  2052. self->mAllScriptsCheck->get();
  2053. bool allow_other_scripts = self->mAllScriptsCheck->get();
  2054. bool allow_publish = false;
  2055. bool mature_publish = self->mMatureCheck->get();
  2056. bool push_restriction = self->mPushRestrictionCheck->get();
  2057. bool see_avs = self->mPrivacyCheck->get();
  2058. bool show_directory = self->mShowDirectoryCheck->get();
  2059. // We have to get the index from a lookup, not from the position in the
  2060. // drop down !
  2061. S32 category_index =
  2062. LLParcel::getCategoryFromString(self->mCategoryCombo->getSelectedValue());
  2063. S32 landing_type_index = self->mTeleportRoutingCombo->getCurrentIndex();
  2064. const LLUUID& snapshot_id = self->mSnapshotCtrl->getImageAssetID();
  2065. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  2066. if (!allow_other_scripts && region && region->getAllowDamage())
  2067. {
  2068. gNotifications.add("UnableToDisableOutsideScripts");
  2069. return;
  2070. }
  2071. // Push data into current parcel
  2072. parcel->setParcelFlag(PF_CREATE_OBJECTS, create_objects);
  2073. parcel->setParcelFlag(PF_CREATE_GROUP_OBJECTS, create_group_objects);
  2074. parcel->setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, all_object_entry);
  2075. parcel->setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, group_object_entry);
  2076. parcel->setParcelFlag(PF_ALLOW_TERRAFORM, allow_terraform);
  2077. parcel->setParcelFlag(PF_ALLOW_DAMAGE, allow_damage);
  2078. parcel->setParcelFlag(PF_ALLOW_FLY, allow_fly);
  2079. // Cannot restrict landmark creation:
  2080. parcel->setParcelFlag(PF_ALLOW_LANDMARK, true);
  2081. parcel->setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, allow_group_scripts);
  2082. parcel->setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, allow_other_scripts);
  2083. parcel->setParcelFlag(PF_SHOW_DIRECTORY, show_directory);
  2084. parcel->setParcelFlag(PF_ALLOW_PUBLISH, allow_publish);
  2085. parcel->setParcelFlag(PF_MATURE_PUBLISH, mature_publish);
  2086. parcel->setParcelFlag(PF_RESTRICT_PUSHOBJECT, push_restriction);
  2087. parcel->setCategory((LLParcel::ECategory)category_index);
  2088. parcel->setLandingType((LLParcel::ELandingType)landing_type_index);
  2089. parcel->setSnapshotID(snapshot_id);
  2090. parcel->setSeeAVs(see_avs);
  2091. // Send current parcel data upstream to server
  2092. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  2093. // Might have changed properties, so let's redraw !
  2094. self->refresh();
  2095. }
  2096. //static
  2097. void LLPanelLandOptions::onClickSet(void* userdata)
  2098. {
  2099. LLPanelLandOptions* self = (LLPanelLandOptions*)userdata;
  2100. if (!self || !self->mParcel) return;
  2101. LLParcel* selected_parcel = self->mParcel->getParcel();
  2102. if (!selected_parcel) return;
  2103. LLParcel* agent_parcel = gViewerParcelMgr.getAgentParcel();
  2104. if (!agent_parcel) return;
  2105. if (agent_parcel->getLocalID() != selected_parcel->getLocalID())
  2106. {
  2107. gNotifications.add("MustBeInParcel");
  2108. return;
  2109. }
  2110. LLVector3 pos_region = gAgent.getPositionAgent();
  2111. selected_parcel->setUserLocation(pos_region);
  2112. selected_parcel->setUserLookAt(gAgent.getFrameAgent().getAtAxis());
  2113. gViewerParcelMgr.sendParcelPropertiesUpdate(selected_parcel);
  2114. self->refresh();
  2115. }
  2116. void LLPanelLandOptions::onClickClear(void* userdata)
  2117. {
  2118. LLPanelLandOptions* self = (LLPanelLandOptions*)userdata;
  2119. if (!self || !self->mParcel) return;
  2120. LLParcel* selected_parcel = self->mParcel->getParcel();
  2121. if (!selected_parcel) return;
  2122. // Yes, this magic number of 0,0,0 means that it is clear
  2123. LLVector3 zero_vec(0.f, 0.f, 0.f);
  2124. selected_parcel->setUserLocation(zero_vec);
  2125. selected_parcel->setUserLookAt(zero_vec);
  2126. gViewerParcelMgr.sendParcelPropertiesUpdate(selected_parcel);
  2127. self->refresh();
  2128. }
  2129. //static
  2130. void LLPanelLandOptions::onClickPublishHelp(void*)
  2131. {
  2132. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  2133. LLParcel* parcel = gViewerParcelMgr.getFloatingParcelSelection()->getParcel();
  2134. llassert(region); // Region should never be null.
  2135. bool can_change_identity = region && parcel ?
  2136. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  2137. GP_LAND_CHANGE_IDENTITY) &&
  2138. !region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH)
  2139. : false;
  2140. if (!can_change_identity)
  2141. {
  2142. gNotifications.add("ClickPublishHelpLandDisabled");
  2143. }
  2144. else
  2145. {
  2146. gNotifications.add("ClickPublishHelpLand");
  2147. }
  2148. }
  2149. //---------------------------------------------------------------------------
  2150. // LLPanelLandAccess
  2151. //---------------------------------------------------------------------------
  2152. LLPanelLandAccess::LLPanelLandAccess(LLParcelSelectionHandle& parcel)
  2153. : LLPanel("land_access_panel"),
  2154. mParcel(parcel),
  2155. mOnlyAllowText(NULL),
  2156. mCheckPublicAccess(NULL),
  2157. mCheckLimitPayment(NULL),
  2158. mCheckLimitAge(NULL),
  2159. mCheckLimitGroup(NULL),
  2160. mCheckLimitPass(NULL),
  2161. mPassCombo(NULL),
  2162. mPriceSpin(NULL),
  2163. mHourSpin(NULL),
  2164. mListAccess(NULL),
  2165. mListBanned(NULL),
  2166. mAddAllowedButton(NULL),
  2167. mRemoveAllowedButton(NULL),
  2168. mAddBannedButton(NULL),
  2169. mRemoveBannedButton(NULL)
  2170. {
  2171. }
  2172. bool LLPanelLandAccess::postBuild()
  2173. {
  2174. mOnlyAllowText = getChild<LLTextBox>("access_label");
  2175. mCheckPublicAccess = getChild<LLCheckBoxCtrl>("public_access");
  2176. mCheckPublicAccess->setCommitCallback(onCommitPublicAccess);
  2177. mCheckPublicAccess->setCallbackUserData(this);
  2178. mCheckLimitPayment = getChild<LLCheckBoxCtrl>("limit_payment");
  2179. mCheckLimitPayment->setCommitCallback(onCommitAny);
  2180. mCheckLimitPayment->setCallbackUserData(this);
  2181. mCheckLimitAge = getChild<LLCheckBoxCtrl>("limit_age_verified");
  2182. mCheckLimitAge->setCommitCallback(onCommitAny);
  2183. mCheckLimitAge->setCallbackUserData(this);
  2184. mCheckLimitGroup = getChild<LLCheckBoxCtrl>("group_access_check");
  2185. mCheckLimitGroup->setCommitCallback(onCommitGroupCheck);
  2186. mCheckLimitGroup->setCallbackUserData(this);
  2187. mCheckLimitPass = getChild<LLCheckBoxCtrl>("pass_access_check");
  2188. mCheckLimitPass->setCommitCallback(onCommitAny);
  2189. mCheckLimitPass->setCallbackUserData(this);
  2190. mPassCombo = getChild<LLComboBox>("pass_combo");
  2191. mPassCombo->setCommitCallback(onCommitAny);
  2192. mPassCombo->setCallbackUserData(this);
  2193. mPriceSpin = getChild<LLSpinCtrl>("price_spin_ctrl");
  2194. mPriceSpin->setCommitCallback(onCommitAny);
  2195. mPriceSpin->setCallbackUserData(this);
  2196. mHourSpin = getChild<LLSpinCtrl>("hours_spin_ctrl");
  2197. mHourSpin->setCommitCallback(onCommitAny);
  2198. mHourSpin->setCallbackUserData(this);
  2199. mAddAllowedButton = getChild<LLButton>("add_allowed");
  2200. mAddAllowedButton->setClickedCallback(onClickAddAccess, this);
  2201. mRemoveAllowedButton = getChild<LLButton>("remove_allowed");
  2202. mRemoveAllowedButton->setClickedCallback(onClickRemoveAccess, this);
  2203. mAddBannedButton = getChild<LLButton>("add_banned");
  2204. mAddBannedButton->setClickedCallback(onClickAddBanned, this);
  2205. mRemoveBannedButton = getChild<LLButton>("remove_banned");
  2206. mRemoveBannedButton->setClickedCallback(onClickRemoveBanned, this);
  2207. mListAccess = getChild<LLNameListCtrl>("access_list");
  2208. mListAccess->sortByColumnIndex(0, true); // Ascending
  2209. mListBanned = getChild<LLNameListCtrl>("banned_list");
  2210. mListBanned->sortByColumnIndex(0, true); // Ascending
  2211. return true;
  2212. }
  2213. //virtual
  2214. LLPanelLandAccess::~LLPanelLandAccess()
  2215. {
  2216. // Release the selection handle
  2217. mParcel = NULL;
  2218. }
  2219. //virtual
  2220. void LLPanelLandAccess::refresh()
  2221. {
  2222. mListAccess->deleteAllItems();
  2223. mListBanned->deleteAllItems();
  2224. // Display options
  2225. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  2226. if (!parcel)
  2227. {
  2228. mCheckPublicAccess->set(false);
  2229. mCheckLimitPayment->set(false);
  2230. mCheckLimitAge->set(false);
  2231. mCheckLimitGroup->set(false);
  2232. mCheckLimitGroup->setLabelArg("[GROUP]", LLStringUtil::null);
  2233. mCheckLimitPass->set(false);
  2234. mPriceSpin->setValue((F32)PARCEL_PASS_PRICE_DEFAULT);
  2235. mHourSpin->setValue(PARCEL_PASS_HOURS_DEFAULT);
  2236. mListAccess->setToolTipArg("[LISTED]", "0");
  2237. mListAccess->setToolTipArg("[MAX]", "0");
  2238. mListBanned->setToolTipArg("[LISTED]", "0");
  2239. mListBanned->setToolTipArg("[MAX]", "0");
  2240. return;
  2241. }
  2242. bool use_access_list = parcel->getParcelFlag(PF_USE_ACCESS_LIST);
  2243. bool use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP);
  2244. bool public_access = !use_access_list;
  2245. // Estate owner may have disabled allowing the parcel owner from managing
  2246. // access
  2247. if (parcel->getRegionAllowAccessOverride())
  2248. {
  2249. mCheckPublicAccess->set(public_access);
  2250. mCheckLimitGroup->set(use_group);
  2251. }
  2252. else
  2253. {
  2254. mCheckPublicAccess->set(true);
  2255. mCheckLimitGroup->set(false);
  2256. }
  2257. std::string group_name;
  2258. if (gCacheNamep)
  2259. {
  2260. gCacheNamep->getGroupName(parcel->getGroupID(), group_name);
  2261. }
  2262. mCheckLimitGroup->setLabelArg("[GROUP]", group_name);
  2263. std::string duration;
  2264. // Allow list
  2265. LLStringUtil::format_map_t args;
  2266. S32 count = parcel->mAccessList.size();
  2267. mListAccess->setToolTipArg("[LISTED]", llformat("%d", count));
  2268. mListAccess->setToolTipArg("[MAX]",
  2269. llformat("%d", PARCEL_MAX_ACCESS_LIST));
  2270. for (access_map_t::const_iterator cit = parcel->mAccessList.begin(),
  2271. end = parcel->mAccessList.end();
  2272. cit != end; ++cit)
  2273. {
  2274. const LLAccessEntry& entry = cit->second;
  2275. if (entry.mTime)
  2276. {
  2277. args["[DURATION]"] = plain_text_duration(entry.mTime - time(NULL));
  2278. duration = getString("remaining", args);
  2279. }
  2280. else
  2281. {
  2282. duration.clear();
  2283. }
  2284. mListAccess->addNameItem(entry.mID, ADD_SORTED, true, duration);
  2285. }
  2286. mListAccess->sortByName(true);
  2287. // Ban List
  2288. std::string always = getString("always");
  2289. count = parcel->mBanList.size();
  2290. mListBanned->setToolTipArg("[LISTED]", llformat("%d", count));
  2291. mListBanned->setToolTipArg("[MAX]",
  2292. llformat("%d", PARCEL_MAX_ACCESS_LIST));
  2293. for (access_map_t::const_iterator cit = parcel->mBanList.begin(),
  2294. end = parcel->mBanList.end();
  2295. cit != end; ++cit)
  2296. {
  2297. const LLAccessEntry& entry = cit->second;
  2298. if (entry.mTime)
  2299. {
  2300. duration = plain_text_duration(entry.mTime - time(NULL));
  2301. if (duration.empty())
  2302. {
  2303. duration = always;
  2304. }
  2305. }
  2306. else
  2307. {
  2308. duration = always;
  2309. }
  2310. LLSD item;
  2311. item["id"] = entry.mID;
  2312. LLSD& columns = item["columns"];
  2313. columns[0]["column"] = "name"; // Value is automatically populated
  2314. columns[1]["column"] = "duration";
  2315. columns[1]["value"] = duration;
  2316. mListBanned->addElement(item);
  2317. }
  2318. mListBanned->sortByName(true);
  2319. if (parcel->getRegionDenyAnonymousOverride())
  2320. {
  2321. mCheckLimitPayment->set(true);
  2322. }
  2323. else
  2324. {
  2325. mCheckLimitPayment->set(parcel->getParcelFlag(PF_DENY_ANONYMOUS));
  2326. }
  2327. if (parcel->getRegionDenyAgeUnverifiedOverride())
  2328. {
  2329. mCheckLimitAge->set(true);
  2330. }
  2331. else
  2332. {
  2333. mCheckLimitAge->set(parcel->getParcelFlag(PF_DENY_AGEUNVERIFIED));
  2334. }
  2335. bool use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST);
  2336. mCheckLimitPass->set(use_pass);
  2337. if (mPassCombo && (public_access || !use_pass))
  2338. {
  2339. mPassCombo->selectByValue("anyone");
  2340. }
  2341. mPriceSpin->setValue((F32)parcel->getPassPrice());
  2342. mHourSpin->setValue(parcel->getPassHours());
  2343. }
  2344. void LLPanelLandAccess::refreshUI()
  2345. {
  2346. if (!mCheckPublicAccess)
  2347. {
  2348. // Something is *very* wrong !
  2349. return;
  2350. }
  2351. mCheckPublicAccess->setEnabled(false);
  2352. mCheckLimitPayment->setEnabled(false);
  2353. mCheckLimitAge->setEnabled(false);
  2354. mCheckLimitGroup->setEnabled(false);
  2355. mCheckLimitPass->setEnabled(false);
  2356. mPassCombo->setEnabled(false);
  2357. mPriceSpin->setEnabled(false);
  2358. mHourSpin->setEnabled(false);
  2359. mListAccess->setEnabled(false);
  2360. mListBanned->setEnabled(false);
  2361. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  2362. if (parcel)
  2363. {
  2364. // Estate owner may have disabled allowing the parcel owner from
  2365. // managing access.
  2366. bool can_manage_allowed = false;
  2367. if (parcel->getRegionAllowAccessOverride())
  2368. {
  2369. can_manage_allowed =
  2370. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  2371. GP_LAND_MANAGE_ALLOWED);
  2372. }
  2373. bool can_manage_banned =
  2374. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  2375. GP_LAND_MANAGE_BANNED);
  2376. bool can_allow_groups = false;
  2377. mCheckPublicAccess->setEnabled(can_manage_allowed);
  2378. bool public_access = mCheckPublicAccess->getValue().asBoolean();
  2379. if (public_access)
  2380. {
  2381. bool overriding = false;
  2382. if (parcel->getRegionDenyAnonymousOverride())
  2383. {
  2384. overriding = true;
  2385. mCheckLimitPayment->setEnabled(false);
  2386. }
  2387. else
  2388. {
  2389. mCheckLimitPayment->setEnabled(can_manage_allowed);
  2390. }
  2391. if (parcel->getRegionDenyAgeUnverifiedOverride())
  2392. {
  2393. overriding = true;
  2394. mCheckLimitAge->setEnabled(false);
  2395. }
  2396. else
  2397. {
  2398. mCheckLimitAge->setEnabled(can_manage_allowed);
  2399. }
  2400. if (overriding)
  2401. {
  2402. mOnlyAllowText->setToolTip(getString("estate_override"));
  2403. }
  2404. else
  2405. {
  2406. mOnlyAllowText->setToolTip(std::string());
  2407. }
  2408. #if 0
  2409. mCheckLimitGroup->setEnabled(false);
  2410. #endif
  2411. mCheckLimitPass->setEnabled(false);
  2412. mPassCombo->setEnabled(false);
  2413. mListAccess->setEnabled(false);
  2414. can_allow_groups = mCheckLimitPayment->getValue().asBoolean() ^
  2415. mCheckLimitAge->getValue().asBoolean();
  2416. }
  2417. else
  2418. {
  2419. can_allow_groups = true;
  2420. mCheckLimitPayment->setEnabled(false);
  2421. mCheckLimitAge->setEnabled(false);
  2422. bool sell_passes = mCheckLimitPass->getValue().asBoolean();
  2423. mCheckLimitPass->setEnabled(can_manage_allowed);
  2424. if (sell_passes)
  2425. {
  2426. mPassCombo->setEnabled(can_manage_allowed);
  2427. mPriceSpin->setEnabled(can_manage_allowed);
  2428. mHourSpin->setEnabled(can_manage_allowed);
  2429. }
  2430. }
  2431. std::string group_name;
  2432. if (gCacheNamep &&
  2433. gCacheNamep->getGroupName(parcel->getGroupID(), group_name))
  2434. {
  2435. mCheckLimitGroup->setEnabled(can_manage_allowed &&
  2436. can_allow_groups);
  2437. }
  2438. mListAccess->setEnabled(can_manage_allowed);
  2439. S32 allowed_list_count = parcel->mAccessList.size();
  2440. mAddAllowedButton->setEnabled(can_manage_allowed &&
  2441. allowed_list_count < PARCEL_MAX_ACCESS_LIST);
  2442. bool has_selected = mListAccess->getFirstSelectedIndex() >= 0;
  2443. mRemoveAllowedButton->setEnabled(can_manage_allowed && has_selected);
  2444. mListBanned->setEnabled(can_manage_banned);
  2445. S32 banned_list_count = parcel->mBanList.size();
  2446. mAddBannedButton->setEnabled(can_manage_banned &&
  2447. banned_list_count < PARCEL_MAX_ACCESS_LIST);
  2448. has_selected = mListBanned->getFirstSelectedIndex() >= 0;
  2449. mRemoveBannedButton->setEnabled(can_manage_banned && has_selected);
  2450. }
  2451. }
  2452. void LLPanelLandAccess::refreshNames()
  2453. {
  2454. if (!mCheckLimitGroup || !mParcel) return;
  2455. std::string group_name;
  2456. LLParcel* parcel = mParcel->getParcel();
  2457. if (parcel && gCacheNamep)
  2458. {
  2459. gCacheNamep->getGroupName(parcel->getGroupID(), group_name);
  2460. }
  2461. mCheckLimitGroup->setLabelArg("[GROUP]", group_name);
  2462. }
  2463. //virtual
  2464. void LLPanelLandAccess::draw()
  2465. {
  2466. refreshUI();
  2467. refreshNames();
  2468. LLPanel::draw();
  2469. }
  2470. //static
  2471. void LLPanelLandAccess::onCommitPublicAccess(LLUICtrl* ctrl, void* userdata)
  2472. {
  2473. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2474. if (!self || !self->mParcel) return;
  2475. LLParcel* parcel = self->mParcel->getParcel();
  2476. if (parcel)
  2477. {
  2478. onCommitAny(ctrl, userdata);
  2479. }
  2480. }
  2481. //static
  2482. void LLPanelLandAccess::onCommitGroupCheck(LLUICtrl* ctrl, void* userdata)
  2483. {
  2484. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2485. if (!self || !self->mParcel) return;
  2486. LLParcel* parcel = self->mParcel->getParcel();
  2487. if (!parcel)
  2488. {
  2489. return;
  2490. }
  2491. bool use_pass_list = !self->mCheckPublicAccess->getValue().asBoolean();
  2492. bool use_access_group = self->mCheckLimitGroup->getValue().asBoolean();
  2493. if (self->mPassCombo && use_access_group && use_pass_list &&
  2494. self->mPassCombo->getSelectedValue().asString() == "group")
  2495. {
  2496. self->mPassCombo->selectByValue("anyone");
  2497. }
  2498. onCommitAny(ctrl, userdata);
  2499. }
  2500. //static
  2501. void LLPanelLandAccess::onCommitAny(LLUICtrl* ctrl, void* userdata)
  2502. {
  2503. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2504. if (!self || !self->mParcel) return;
  2505. LLParcel* parcel = self->mParcel->getParcel();
  2506. if (!parcel)
  2507. {
  2508. return;
  2509. }
  2510. // Extract data from UI
  2511. bool public_access = self->mCheckPublicAccess->getValue().asBoolean();
  2512. bool use_access_group = self->mCheckLimitGroup->getValue().asBoolean();
  2513. if (use_access_group)
  2514. {
  2515. std::string group_name;
  2516. if (!gCacheNamep ||
  2517. !gCacheNamep->getGroupName(parcel->getGroupID(), group_name))
  2518. {
  2519. use_access_group = false;
  2520. }
  2521. }
  2522. bool limit_payment = false;
  2523. bool limit_age_verified = false;
  2524. bool use_access_list = false;
  2525. bool use_pass_list = false;
  2526. if (public_access)
  2527. {
  2528. use_access_list = false;
  2529. limit_payment = self->mCheckLimitPayment->getValue().asBoolean();
  2530. limit_age_verified = self->mCheckLimitAge->getValue().asBoolean();
  2531. }
  2532. else
  2533. {
  2534. use_access_list = true;
  2535. use_pass_list = self->mCheckLimitPass->getValue().asBoolean();
  2536. if (self->mPassCombo && use_access_group && use_pass_list &&
  2537. self->mPassCombo->getSelectedValue().asString() == "group")
  2538. {
  2539. use_access_group = false;
  2540. }
  2541. }
  2542. S32 pass_price = llfloor((F32)self->mPriceSpin->getValue().asReal());
  2543. F32 pass_hours = (F32)self->mHourSpin->getValue().asReal();
  2544. // Push data into current parcel
  2545. parcel->setParcelFlag(PF_USE_ACCESS_GROUP, use_access_group);
  2546. parcel->setParcelFlag(PF_USE_ACCESS_LIST, use_access_list);
  2547. parcel->setParcelFlag(PF_USE_PASS_LIST, use_pass_list);
  2548. parcel->setParcelFlag(PF_USE_BAN_LIST, true);
  2549. parcel->setParcelFlag(PF_DENY_ANONYMOUS, limit_payment);
  2550. parcel->setParcelFlag(PF_DENY_AGEUNVERIFIED, limit_age_verified);
  2551. parcel->setPassPrice(pass_price);
  2552. parcel->setPassHours(pass_hours);
  2553. // Send current parcel data upstream to server
  2554. gViewerParcelMgr.sendParcelPropertiesUpdate(parcel);
  2555. // Might have changed properties, so let's redraw!
  2556. self->refresh();
  2557. }
  2558. //static
  2559. void LLPanelLandAccess::onClickAddAccess(void* userdata)
  2560. {
  2561. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2562. if (!self || !self->mParcel || !gFloaterViewp) return;
  2563. LLFloaterAvatarPicker* picker =
  2564. LLFloaterAvatarPicker::show(callbackAvatarCBAccess, userdata);
  2565. if (picker)
  2566. {
  2567. LLFloater* parent = gFloaterViewp->getParentFloater(self);
  2568. if (parent)
  2569. {
  2570. parent->addDependentFloater(picker);
  2571. }
  2572. }
  2573. }
  2574. //static
  2575. void LLPanelLandAccess::callbackAvatarCBAccess(const std::vector<std::string>& names,
  2576. const uuid_vec_t& ids,
  2577. void* userdata)
  2578. {
  2579. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2580. if (self && self->mParcel && !names.empty() && !ids.empty())
  2581. {
  2582. LLUUID id = ids[0];
  2583. LLParcel* parcel = self->mParcel->getParcel();
  2584. if (parcel)
  2585. {
  2586. parcel->addToAccessList(id, 0);
  2587. gViewerParcelMgr.sendParcelAccessListUpdate(AL_ACCESS);
  2588. self->refresh();
  2589. }
  2590. }
  2591. }
  2592. //static
  2593. void LLPanelLandAccess::onClickRemoveAccess(void* userdata)
  2594. {
  2595. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2596. if (self && self->mParcel)
  2597. {
  2598. LLParcel* parcel = self->mParcel->getParcel();
  2599. if (parcel)
  2600. {
  2601. std::vector<LLScrollListItem*> names =
  2602. self->mListAccess->getAllSelected();
  2603. for (std::vector<LLScrollListItem*>::iterator iter = names.begin();
  2604. iter != names.end();)
  2605. {
  2606. LLScrollListItem* item = *iter++;
  2607. const LLUUID& agent_id = item->getUUID();
  2608. parcel->removeFromAccessList(agent_id);
  2609. }
  2610. gViewerParcelMgr.sendParcelAccessListUpdate(AL_ACCESS);
  2611. self->refresh();
  2612. }
  2613. }
  2614. }
  2615. //static
  2616. void LLPanelLandAccess::onClickAddBanned(void* userdata)
  2617. {
  2618. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2619. if (!self || !self->mParcel || !gFloaterViewp) return;
  2620. LLFloaterAvatarPicker* picker =
  2621. LLFloaterAvatarPicker::show(callbackAvatarCBBanned, userdata, true);
  2622. if (picker)
  2623. {
  2624. LLFloater* parent = gFloaterViewp->getParentFloater(self);
  2625. if (parent)
  2626. {
  2627. parent->addDependentFloater(picker);
  2628. }
  2629. }
  2630. }
  2631. //static
  2632. void LLPanelLandAccess::callbackAvatarCBBanned(const std::vector<std::string>& names,
  2633. const uuid_vec_t& ids,
  2634. void* userdata)
  2635. {
  2636. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2637. if (!self || !self->mParcel || !gFloaterViewp) return;
  2638. LLFloaterBanDuration* duration =
  2639. LLFloaterBanDuration::show(ids, callbackAvatarCBBanned2, self);
  2640. if (duration)
  2641. {
  2642. LLFloater* parent = gFloaterViewp->getParentFloater(self);
  2643. if (parent)
  2644. {
  2645. parent->addDependentFloater(duration);
  2646. }
  2647. }
  2648. }
  2649. //static
  2650. void LLPanelLandAccess::callbackAvatarCBBanned2(const uuid_vec_t& ids,
  2651. S32 duration, void* userdata)
  2652. {
  2653. LLPanelLandAccess* self = (LLPanelLandAccess*)userdata;
  2654. if (!self || !self->mParcel || ids.empty()) return;
  2655. LLParcel* parcel = self->mParcel->getParcel();
  2656. if (!parcel) return;
  2657. U32 lists_to_update = 0;
  2658. for (U32 i = 0, count = ids.size(); i < count; ++i)
  2659. {
  2660. const LLUUID& id = ids[i];
  2661. if (parcel->addToBanList(id, duration))
  2662. {
  2663. LL_DEBUGS("ParcelAccess") << "Resident " << id
  2664. << " added to ban list for " << duration
  2665. << " seconds" << LL_ENDL;
  2666. lists_to_update |= AL_BAN;
  2667. // The resident was successfully added to the ban list but we also
  2668. // need to check access list to ensure that agent will not be in
  2669. // two lists simultaneously...
  2670. if (parcel->removeFromAccessList(id))
  2671. {
  2672. lists_to_update |= AL_ACCESS;
  2673. LL_DEBUGS("ParcelAccess") << "Resident " << id
  2674. << " removed from access list"
  2675. << LL_ENDL;
  2676. }
  2677. }
  2678. }
  2679. if (lists_to_update)
  2680. {
  2681. gViewerParcelMgr.sendParcelAccessListUpdate(lists_to_update);
  2682. self->refresh();
  2683. }
  2684. }
  2685. //static
  2686. void LLPanelLandAccess::onClickRemoveBanned(void* data)
  2687. {
  2688. LLPanelLandAccess* self = (LLPanelLandAccess*)data;
  2689. if (self && self->mParcel && self->mListBanned)
  2690. {
  2691. LLParcel* parcel = self->mParcel->getParcel();
  2692. if (parcel)
  2693. {
  2694. std::vector<LLScrollListItem*> names = self->mListBanned->getAllSelected();
  2695. for (std::vector<LLScrollListItem*>::iterator iter = names.begin();
  2696. iter != names.end(); )
  2697. {
  2698. LLScrollListItem* item = *iter++;
  2699. const LLUUID& agent_id = item->getUUID();
  2700. parcel->removeFromBanList(agent_id);
  2701. }
  2702. gViewerParcelMgr.sendParcelAccessListUpdate(AL_BAN);
  2703. self->refresh();
  2704. }
  2705. }
  2706. }
  2707. //---------------------------------------------------------------------------
  2708. // LLPanelLandCovenant
  2709. //---------------------------------------------------------------------------
  2710. LLPanelLandCovenant::LLPanelLandCovenant(LLParcelSelectionHandle& parcel)
  2711. : LLPanel("land_covenant_panel"),
  2712. mParcel(parcel),
  2713. mRegionNameText(NULL),
  2714. mRegionTypeText(NULL),
  2715. mRegionMaturityText(NULL),
  2716. mRegionResellClauseText(NULL),
  2717. mRegionChangeClauseText(NULL),
  2718. mEstateNameText(NULL),
  2719. mEstateOwnerText(NULL),
  2720. mCovenantDateText(NULL),
  2721. mCovenantEditor(NULL)
  2722. {
  2723. }
  2724. //virtual
  2725. LLPanelLandCovenant::~LLPanelLandCovenant()
  2726. {
  2727. // Release the selection handle
  2728. mParcel = NULL;
  2729. }
  2730. bool LLPanelLandCovenant::postBuild()
  2731. {
  2732. mRegionNameText = getChild<LLTextBox>("region_name_text");
  2733. mRegionTypeText = getChild<LLTextBox>("region_landtype_text");
  2734. mRegionMaturityText = getChild<LLTextBox>("region_maturity_text");
  2735. mRegionResellClauseText = getChild<LLTextBox>("resellable_clause");
  2736. mRegionChangeClauseText = getChild<LLTextBox>("changeable_clause");
  2737. mEstateNameText = getChild<LLTextBox>("estate_name_text");
  2738. mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
  2739. mCovenantDateText = getChild<LLTextBox>("covenant_timestamp_text");
  2740. mCovenantEditor = getChild<LLViewerTextEditor>("covenant_editor");
  2741. refresh();
  2742. return true;
  2743. }
  2744. //virtual
  2745. void LLPanelLandCovenant::refresh()
  2746. {
  2747. LLViewerRegion* region = gViewerParcelMgr.getSelectionRegion();
  2748. if (!region) return;
  2749. mRegionNameText->setText(region->getName());
  2750. mRegionTypeText->setText(region->getSimProductName());
  2751. mRegionMaturityText->setText(region->getSimAccessString());
  2752. if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
  2753. {
  2754. mRegionResellClauseText->setText(getString("can_not_resell"));
  2755. }
  2756. else
  2757. {
  2758. mRegionResellClauseText->setText(getString("can_resell"));
  2759. }
  2760. if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
  2761. {
  2762. mRegionChangeClauseText->setText(getString("can_change"));
  2763. }
  2764. else
  2765. {
  2766. mRegionChangeClauseText->setText(getString("can_not_change"));
  2767. }
  2768. // Send EstateCovenantInfo message
  2769. region->sendEstateCovenantRequest();
  2770. }
  2771. //static
  2772. void LLPanelLandCovenant::updateCovenantText(const std::string &string)
  2773. {
  2774. LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
  2775. if (self)
  2776. {
  2777. self->mCovenantEditor->setHandleEditKeysDirectly(true);
  2778. self->mCovenantEditor->setText(string);
  2779. }
  2780. }
  2781. //static
  2782. void LLPanelLandCovenant::updateLastModified(const std::string& text)
  2783. {
  2784. LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
  2785. if (self)
  2786. {
  2787. self->mCovenantDateText->setText(text);
  2788. }
  2789. }
  2790. //static
  2791. void LLPanelLandCovenant::updateEstateName(const std::string& name)
  2792. {
  2793. LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
  2794. if (self)
  2795. {
  2796. self->mEstateNameText->setText(name);
  2797. }
  2798. }
  2799. //static
  2800. void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name)
  2801. {
  2802. LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
  2803. if (self)
  2804. {
  2805. self->mEstateOwnerText->setText(name);
  2806. }
  2807. }
  2808. //---------------------------------------------------------------------------
  2809. // LLPanelLandExperiences
  2810. //---------------------------------------------------------------------------
  2811. //static
  2812. void* LLPanelLandExperiences::createAllowedExperiencesPanel(void* data)
  2813. {
  2814. LLPanelLandExperiences* self = (LLPanelLandExperiences*)data;
  2815. self->mAllowed = new LLPanelExperienceListEditor();
  2816. return self->mAllowed;
  2817. }
  2818. //static
  2819. void* LLPanelLandExperiences::createBlockedExperiencesPanel(void* data)
  2820. {
  2821. LLPanelLandExperiences* self = (LLPanelLandExperiences*)data;
  2822. self->mBlocked = new LLPanelExperienceListEditor();
  2823. return self->mBlocked;
  2824. }
  2825. LLPanelLandExperiences::LLPanelLandExperiences(LLSafeHandle<LLParcelSelection>& parcelp)
  2826. : mParcel(parcelp)
  2827. {
  2828. LLCallbackMap::map_t factory_map;
  2829. factory_map["panel_allowed"] = LLCallbackMap(createAllowedExperiencesPanel,
  2830. this);
  2831. factory_map["panel_blocked"] = LLCallbackMap(createBlockedExperiencesPanel,
  2832. this);
  2833. LLUICtrlFactory::getInstance()->buildPanel(this,
  2834. "panel_region_experiences.xml",
  2835. &factory_map);
  2836. }
  2837. //virtual
  2838. LLPanelLandExperiences::~LLPanelLandExperiences()
  2839. {
  2840. // Release the selection handle
  2841. mParcel = NULL;
  2842. }
  2843. bool LLPanelLandExperiences::postBuild()
  2844. {
  2845. if (!mAllowed || !mBlocked) return false;
  2846. setupList(mAllowed, "panel_allowed",
  2847. EXPERIENCE_KEY_TYPE_ALLOWED, AL_ALLOW_EXPERIENCE);
  2848. setupList(mBlocked, "panel_blocked",
  2849. EXPERIENCE_KEY_TYPE_BLOCKED, AL_BLOCK_EXPERIENCE);
  2850. // Only non-grid-wide experiences
  2851. mAllowed->addFilter(boost::bind(LLExperienceCache::FilterWithProperty,
  2852. _1, LLExperienceCache::PROPERTY_GRID));
  2853. // No privileged ones
  2854. mBlocked->addFilter(boost::bind(LLExperienceCache::FilterWithoutProperties,
  2855. _1,
  2856. LLExperienceCache::PROPERTY_PRIVILEGED |
  2857. LLExperienceCache::PROPERTY_GRID));
  2858. getChild<LLPanel>("trusted_layout_panel")->setVisible(false);
  2859. getChild<LLPanel>("help_text_layout_panel")->setVisible(false);
  2860. mAllowed->getChild<LLTextBox>("text_name")->setToolTip(getString("allowed_parcel_text"));
  2861. mBlocked->getChild<LLTextBox>("text_name")->setToolTip(getString("blocked_parcel_text"));
  2862. return LLPanel::postBuild();
  2863. }
  2864. void LLPanelLandExperiences::setupList(LLPanelExperienceListEditor* panel,
  2865. const std::string& control_name,
  2866. U32 xp_type,
  2867. U32 access_type)
  2868. {
  2869. if (!panel) return;
  2870. panel->getChild<LLTextBox>("text_name")->setText(panel->getString(control_name));
  2871. panel->setMaxExperienceIDs(PARCEL_MAX_EXPERIENCE_LIST);
  2872. panel->setAddedCallback(boost::bind(&LLPanelLandExperiences::experienceAdded,
  2873. this, _1, xp_type, access_type));
  2874. panel->setRemovedCallback(boost::bind(&LLPanelLandExperiences::experienceRemoved,
  2875. this, _1, access_type));
  2876. }
  2877. void LLPanelLandExperiences::experienceAdded(const LLUUID& id, U32 xp_type,
  2878. U32 access_type)
  2879. {
  2880. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  2881. if (parcel)
  2882. {
  2883. parcel->setExperienceKeyType(id, xp_type);
  2884. gViewerParcelMgr.sendParcelAccessListUpdate(access_type);
  2885. refresh();
  2886. }
  2887. }
  2888. void LLPanelLandExperiences::experienceRemoved(const LLUUID& id,
  2889. U32 access_type)
  2890. {
  2891. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  2892. if (parcel)
  2893. {
  2894. parcel->setExperienceKeyType(id, EXPERIENCE_KEY_TYPE_NONE);
  2895. gViewerParcelMgr.sendParcelAccessListUpdate(access_type);
  2896. refresh();
  2897. }
  2898. }
  2899. void LLPanelLandExperiences::refreshPanel(LLPanelExperienceListEditor* panel,
  2900. U32 xp_type)
  2901. {
  2902. if (!panel) return;
  2903. LLParcel* parcel = mParcel ? mParcel->getParcel() : NULL;
  2904. if (!parcel)
  2905. {
  2906. // Disable the panel
  2907. panel->setReadonly();
  2908. panel->setDisabled();
  2909. panel->setExperienceIds(LLSD::emptyArray());
  2910. return;
  2911. }
  2912. panel->setDisabled(false);
  2913. // Enable the panel, as read only or not depending on permissions
  2914. bool can_modify =
  2915. LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  2916. GP_LAND_OPTIONS);
  2917. panel->setReadonly(!can_modify);
  2918. access_map_t entries = parcel->getExperienceKeysByType(xp_type);
  2919. LLSD ids = LLSD::emptyArray();
  2920. for (access_map_t::iterator it = entries.begin(), end = entries.end();
  2921. it != end; ++it)
  2922. {
  2923. ids.append(it->second.mID);
  2924. }
  2925. panel->setExperienceIds(ids);
  2926. panel->refreshExperienceCounter();
  2927. }
  2928. //virtual
  2929. void LLPanelLandExperiences::refresh()
  2930. {
  2931. refreshPanel(mAllowed, EXPERIENCE_KEY_TYPE_ALLOWED);
  2932. refreshPanel(mBlocked, EXPERIENCE_KEY_TYPE_BLOCKED);
  2933. }