hbfloatereditenvsettings.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. /**
  2. * @file hbfloatereditenvsettings.cpp
  3. * @brief Environment settings editor floater class implementation
  4. *
  5. * $LicenseInfo:firstyear=2018&license=viewergpl$
  6. *
  7. * Copyright (c) 2019-2023 Henri Beauchamp
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "hbfloatereditenvsettings.h"
  34. #include "llbutton.h"
  35. #include "llcheckboxctrl.h"
  36. #include "llcombobox.h"
  37. #include "hbfileselector.h"
  38. #include "lllineeditor.h"
  39. #include "llnotifications.h"
  40. #include "llsliderctrl.h"
  41. #include "lltrans.h"
  42. #include "lluictrlfactory.h"
  43. #include "llagent.h"
  44. #include "llappviewer.h" // For gFrameTimeSeconds
  45. #include "llenvsettings.h"
  46. #include "llinventorymodel.h"
  47. #include "hbfloaterinvitemspicker.h"
  48. #include "llpanelenvsettings.h"
  49. //MK
  50. #include "mkrlinterface.h"
  51. //mk
  52. #include "llviewercontrol.h"
  53. #include "llviewerinventory.h"
  54. #include "llviewerparcelmgr.h"
  55. // Helper class
  56. class HBSettingsCopiedCallback final : public LLInventoryCallback
  57. {
  58. public:
  59. HBSettingsCopiedCallback(LLHandle<LLFloater> handle)
  60. : mHandle(handle)
  61. {
  62. }
  63. void fire(const LLUUID& inv_item_id) override
  64. {
  65. if (!mHandle.isDead() && gInventory.getItem(inv_item_id))
  66. {
  67. HBFloaterEditEnvSettings* floaterp =
  68. (HBFloaterEditEnvSettings*)mHandle.get();
  69. floaterp->onInventoryCreated(inv_item_id, true);
  70. }
  71. }
  72. private:
  73. LLHandle<LLFloater> mHandle;
  74. };
  75. ///////////////////////////////////////////////////////////////////////////////
  76. // HBFloaterEditEnvSettings class proper
  77. ///////////////////////////////////////////////////////////////////////////////
  78. //static
  79. HBFloaterEditEnvSettings::instances_map_t HBFloaterEditEnvSettings::sInstances;
  80. //static
  81. HBFloaterEditEnvSettings* HBFloaterEditEnvSettings::show(LLUUID inv_id)
  82. {
  83. if (inv_id.isNull())
  84. {
  85. llwarns << "Null item Id passed. Floater not created." << llendl;
  86. return NULL;
  87. }
  88. // Make sure we are not trying to edit a link and get the linked item Id
  89. // in that case.
  90. inv_id = gInventory.getLinkedItemID(inv_id);
  91. HBFloaterEditEnvSettings* self = NULL;
  92. instances_map_t::iterator it = sInstances.find(inv_id);
  93. if (it == sInstances.end())
  94. {
  95. LLViewerInventoryItem* itemp = gInventory.getItem(inv_id);
  96. if (!itemp || itemp->getIsBrokenLink())
  97. {
  98. llwarns << "Could not find inventory item, Id: " << inv_id
  99. << llendl;
  100. return NULL;
  101. }
  102. if (!itemp->isSettingsType())
  103. {
  104. llwarns << "Inventory item " << inv_id
  105. << " is not an environment settings item. Floater not created."
  106. << llendl;
  107. return NULL;
  108. }
  109. LLSettingsType::EType type = itemp->getSettingsType();
  110. if (type != LLSettingsType::ST_SKY &&
  111. type != LLSettingsType::ST_WATER &&
  112. type != LLSettingsType::ST_DAYCYCLE)
  113. {
  114. llwarns << "Invalid environment settings type: " << type
  115. << ". Floater not created." << llendl;
  116. return NULL;
  117. }
  118. self = new HBFloaterEditEnvSettings(inv_id, type);
  119. sInstances[inv_id] = self;
  120. }
  121. else
  122. {
  123. self = it->second;
  124. }
  125. if (self)
  126. {
  127. self->open();
  128. self->setFocus(true);
  129. }
  130. return self;
  131. }
  132. //static
  133. HBFloaterEditEnvSettings* HBFloaterEditEnvSettings::create(LLSettingsType::EType type)
  134. {
  135. if (type != LLSettingsType::ST_SKY && type != LLSettingsType::ST_WATER &&
  136. type != LLSettingsType::ST_DAYCYCLE)
  137. {
  138. llwarns << "Invalid environment settings type: " << type
  139. << ". Floater not created." << llendl;
  140. return NULL;
  141. }
  142. HBFloaterEditEnvSettings* self = new HBFloaterEditEnvSettings(LLUUID::null,
  143. type);
  144. if (self)
  145. {
  146. self->open();
  147. self->setFocus(true);
  148. }
  149. return self;
  150. }
  151. //static
  152. void HBFloaterEditEnvSettings::destroy(const LLUUID& inv_id)
  153. {
  154. instances_map_t::iterator it = sInstances.find(inv_id);
  155. if (it != sInstances.end())
  156. {
  157. // Let it no chance to save anything...
  158. HBFloaterEditEnvSettings* self = it->second;
  159. self->setDirty(false);
  160. self->close();
  161. }
  162. }
  163. //static
  164. void* HBFloaterEditEnvSettings::createSettingsPanel(void* userdata)
  165. {
  166. HBFloaterEditEnvSettings* self = (HBFloaterEditEnvSettings*)userdata;
  167. switch (self->mSettingsType)
  168. {
  169. case LLSettingsType::ST_SKY:
  170. self->mEditPanel = new LLPanelEnvSettingsSky();
  171. break;
  172. case LLSettingsType::ST_WATER:
  173. self->mEditPanel = new LLPanelEnvSettingsWater();
  174. break;
  175. case LLSettingsType::ST_DAYCYCLE:
  176. self->mEditPanel = new LLPanelEnvSettingsDay();
  177. break;
  178. default:
  179. llerrs << "Unknown settings type !" << llendl;
  180. }
  181. return self->mEditPanel;
  182. }
  183. HBFloaterEditEnvSettings::HBFloaterEditEnvSettings(const LLUUID& inv_id,
  184. LLSettingsType::EType type)
  185. : mInventoryId(inv_id),
  186. mSettingsType(type),
  187. mInventoryItem(NULL),
  188. mSaveAsNewCounter(0),
  189. mCanSave(false),
  190. mCanCopy(false),
  191. mCanModify(false),
  192. mCanTransfer(false)
  193. {
  194. LLCallbackMap::map_t factory_map;
  195. factory_map["settings_panel"] = LLCallbackMap(createSettingsPanel, this);
  196. LLUICtrlFactory::getInstance()->buildFloater(this,
  197. "floater_edit_settings.xml",
  198. &factory_map, false);
  199. }
  200. //virtual
  201. HBFloaterEditEnvSettings::~HBFloaterEditEnvSettings()
  202. {
  203. if (mInventoryId.notNull())
  204. {
  205. sInstances.erase(mInventoryId);
  206. }
  207. }
  208. //virtual
  209. bool HBFloaterEditEnvSettings::postBuild()
  210. {
  211. std::string title = getTitle();
  212. switch (mSettingsType)
  213. {
  214. case LLSettingsType::ST_SKY:
  215. title = getString("edit_sky");
  216. break;
  217. case LLSettingsType::ST_WATER:
  218. title = getString("edit_water");
  219. break;
  220. case LLSettingsType::ST_DAYCYCLE:
  221. title = getString("edit_daycycle");
  222. break;
  223. default:
  224. // This shall never happen because of the llerrs in
  225. // createSettingsPanel() default path
  226. break;
  227. }
  228. setTitle(title);
  229. mLoadBtn = getChild<LLButton>("btn_load");
  230. mLoadBtn->setClickedCallback(onButtonLoad, this);
  231. mImportBtn = getChild<LLButton>("btn_import");
  232. mImportBtn->setClickedCallback(onButtonImport, this);
  233. mCancelBtn = getChild<LLButton>("btn_cancel");
  234. mCancelBtn->setClickedCallback(onButtonCancel, this);
  235. mApplyBtn = getChild<LLFlyoutButton>("btn_apply");
  236. mApplyBtn->setCommitCallback(onButtonApply);
  237. mApplyBtn->setCallbackUserData(this);
  238. mSaveBtn = getChild<LLButton>("btn_save");
  239. mSaveBtn->setClickedCallback(onButtonSave, this);
  240. mSaveAsNewBtn = getChild<LLButton>("btn_save_as_new");
  241. mSaveAsNewBtn->setClickedCallback(onButtonSaveAsNew, this);
  242. mNameEditor = getChild<LLLineEditor>("settings_name");
  243. mNameEditor->setPrevalidate(LLLineEditor::prevalidateASCII);
  244. mNameEditor->setCommitOnFocusLost(true);
  245. mNameEditor->setCommitCallback(onNameChanged);
  246. mNameEditor->setCallbackUserData(this);
  247. // Reduce the floater size for Water and Sky settings, that got a smaller
  248. // panel. The height difference is kept as a "string" element in the
  249. // floater xml file.
  250. if (mSettingsType != LLSettingsType::ST_DAYCYCLE)
  251. {
  252. const LLRect& rect = getRect();
  253. std::string delta = getString("DELTA_HEIGHT");
  254. reshape(rect.getWidth(), rect.getHeight() - atoi(delta.c_str()));
  255. }
  256. // Place it in a smart way, like preview floaters...
  257. S32 left, top;
  258. gFloaterViewp->getNewFloaterPosition(&left, &top);
  259. translate(left - getRect().mLeft, top - getRect().mTop);
  260. gFloaterViewp->adjustToFitScreen(this);
  261. loadInventoryItem(mInventoryId);
  262. return true;
  263. }
  264. static void close_confirm_cb(const LLSD& notification, const LLSD& response,
  265. void* userdata)
  266. {
  267. if (userdata &&
  268. LLNotification::getSelectedOption(notification, response) == 0)
  269. {
  270. HBFloaterEditEnvSettings* floaterp = (HBFloaterEditEnvSettings*)userdata;
  271. floaterp->setDirty(false);
  272. floaterp->close();
  273. }
  274. }
  275. //virtual
  276. void HBFloaterEditEnvSettings::onClose(bool app_quitting)
  277. {
  278. if (!app_quitting)
  279. {
  280. if (isDirty())
  281. {
  282. gNotifications.add("SettingsConfirmLoss", LLSD(), LLSD(),
  283. boost::bind(&close_confirm_cb, _1, _2, this));
  284. return;
  285. }
  286. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
  287. gEnvironment.setCurrentEnvironmentSelection(LLEnvironment::ENV_LOCAL);
  288. gEnvironment.clearEnvironment(LLEnvironment::ENV_EDIT);
  289. }
  290. LLFloater::onClose(app_quitting);
  291. }
  292. //virtual
  293. void HBFloaterEditEnvSettings::onFocusReceived()
  294. {
  295. if (isInVisibleChain())
  296. {
  297. gSavedSettings.setBool("UseParcelEnvironment", true);
  298. updateEditEnvironment();
  299. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_EDIT,
  300. LLEnvironment::TRANSITION_FAST);
  301. }
  302. LLFloater::onFocusReceived();
  303. }
  304. //virtual
  305. void HBFloaterEditEnvSettings::refresh()
  306. {
  307. if (!mEditPanel->settingsValid())
  308. {
  309. mNameEditor->setEnabled(false);
  310. mApplyBtn->setEnabled(false);
  311. mSaveAsNewBtn->setEnabled(false);
  312. return;
  313. }
  314. if (mEditPanel->getEditContext() < LLPanelEnvSettings::CONTEXT_PARCEL)
  315. {
  316. mNameEditor->setText(mEditPanel->getSettingsName());
  317. mNameEditor->setEnabled(mCanModify);
  318. mApplyBtn->setEnabled(true);
  319. mSaveAsNewBtn->setEnabled(mCanCopy && mCanSave);
  320. }
  321. else
  322. {
  323. mNameEditor->setEnabled(false);
  324. }
  325. mEditPanel->setCanEdit(mCanModify);
  326. mEditPanel->refresh();
  327. LLFloater::refresh();
  328. }
  329. //virtual
  330. void HBFloaterEditEnvSettings::draw()
  331. {
  332. mSaveBtn->setEnabled(mCanModify && mCanSave && isDirty() &&
  333. mNameEditor->getLength() > 0);
  334. // Refresh the state of the buttons that depend on the file selector
  335. // availability, whenever the latter changed.
  336. static bool can_use_file_selector = false;
  337. bool available = !HBFileSelector::isInUse();
  338. if (available != can_use_file_selector)
  339. {
  340. can_use_file_selector = available;
  341. mImportBtn->setEnabled(available);
  342. mEditPanel->setFileLoadingAvailable(available);
  343. }
  344. LLFloater::draw();
  345. }
  346. bool HBFloaterEditEnvSettings::isDirty() const
  347. {
  348. return mEditPanel->settingsValid() && mEditPanel->isDirty();
  349. }
  350. void HBFloaterEditEnvSettings::setDirty(bool dirty)
  351. {
  352. mEditPanel->setDirty(dirty);
  353. }
  354. void HBFloaterEditEnvSettings::setEditContextInventory()
  355. {
  356. mEditPanel->setEditContext(LLPanelEnvSettings::CONTEXT_INVENTORY);
  357. mSaveBtn->setToolTip(getString("tip_save_inventory"));
  358. mApplyBtn->setVisible(true);
  359. mSaveAsNewBtn->setVisible(true);
  360. }
  361. void HBFloaterEditEnvSettings::setEditContextParcel()
  362. {
  363. mEditPanel->setEditContext(LLPanelEnvSettings::CONTEXT_PARCEL);
  364. mSaveBtn->setToolTip(getString("tip_save_parcel"));
  365. mApplyBtn->setVisible(false);
  366. mSaveAsNewBtn->setVisible(false);
  367. mNameEditor->setText(getString("parcel_settings"));
  368. }
  369. void HBFloaterEditEnvSettings::setEditContextRegion()
  370. {
  371. mEditPanel->setEditContext(LLPanelEnvSettings::CONTEXT_REGION);
  372. mSaveBtn->setToolTip(getString("tip_save_region"));
  373. mApplyBtn->setVisible(false);
  374. mSaveAsNewBtn->setVisible(false);
  375. mNameEditor->setText(getString("region_settings"));
  376. }
  377. void HBFloaterEditEnvSettings::setDayLength(S32 seconds)
  378. {
  379. LLPanelEnvSettingsDay* panelp =
  380. dynamic_cast<LLPanelEnvSettingsDay*>(mEditPanel);
  381. if (panelp)
  382. {
  383. panelp->setDayLength(seconds);
  384. }
  385. }
  386. HBFloaterEditEnvSettings::connection_t HBFloaterEditEnvSettings::setCommitCB(commit_cb_t cb)
  387. {
  388. return mCommitSignal.connect(cb);
  389. }
  390. void HBFloaterEditEnvSettings::loadInventoryItem(LLUUID inv_id,
  391. const std::string& notify)
  392. {
  393. // Make sure we are not trying to edit a link and get the linked item Id
  394. // in that case.
  395. if (inv_id.notNull())
  396. {
  397. inv_id = gInventory.getLinkedItemID(inv_id);
  398. }
  399. if (mInventoryId != inv_id &&
  400. // Do not register our floater when we are editing parcel or region
  401. // settings
  402. mEditPanel->getEditContext() <= LLPanelEnvSettings::CONTEXT_INVENTORY)
  403. {
  404. // Remove any old instance
  405. if (mInventoryId.notNull() && sInstances.count(mInventoryId))
  406. {
  407. sInstances.erase(mInventoryId);
  408. }
  409. // Register our instance as associated with the new inventory item, if
  410. // any.
  411. if (inv_id.notNull())
  412. {
  413. if (sInstances.count(inv_id))
  414. {
  415. llwarns << "Another floater is opened for inventory item: "
  416. << inv_id << ". Closing this floater." << llendl;
  417. // Do not remove the other instance entry in destructor for
  418. // this floater...
  419. mInventoryId.setNull();
  420. setDirty(false);
  421. close();
  422. return;
  423. }
  424. sInstances[inv_id] = this;
  425. }
  426. mInventoryId = inv_id;
  427. }
  428. if (inv_id.isNull())
  429. {
  430. // This is an import of legacy Windlight settings, or a floater opened
  431. // from HBPanelLandEnvironment for a custom environment.
  432. mInventoryId.setNull();
  433. mInventoryItem = NULL;
  434. mCanSave = mCanCopy = mCanModify = mCanTransfer = true;
  435. return;
  436. }
  437. mInventoryItem = gInventory.getItem(inv_id);
  438. if (!mInventoryItem || mInventoryItem->getIsBrokenLink())
  439. {
  440. llwarns << "Could not find inventory item: " << inv_id
  441. << ". Closing floater." << llendl;
  442. gNotifications.add("CantFindInvItem");
  443. setDirty(false);
  444. close();
  445. return;
  446. }
  447. if (!mInventoryItem->isSettingsType())
  448. {
  449. llwarns << "Inventory item " << inv_id
  450. << " is not an environment settings item. Closing floater."
  451. << llendl;
  452. gNotifications.add("UnableEditItem");
  453. setDirty(false);
  454. close();
  455. return;
  456. }
  457. LLSettingsType::EType type = mInventoryItem->getSettingsType();
  458. if (type != mSettingsType)
  459. {
  460. llwarns << "Bad environment settings type for inventory item: "
  461. << inv_id << ". Was expecting type " << mSettingsType
  462. << " and got type " << type << ". Closing floater." << llendl;
  463. gNotifications.add("UnableEditItem");
  464. setDirty(false);
  465. close();
  466. return;
  467. }
  468. const LLUUID& asset_id = mInventoryItem->getAssetUUID();
  469. if (asset_id.isNull())
  470. {
  471. llwarns << "Null asset Id for inventory item: " << inv_id
  472. << ". Closing floater." << llendl;
  473. gNotifications.add("UnableEditItem");
  474. setDirty(false);
  475. close();
  476. return;
  477. }
  478. if (!notify.empty())
  479. {
  480. LLSD args;
  481. args["NAME"] = mInventoryItem->getName();
  482. gNotifications.add(notify, args);
  483. }
  484. // *TODO: should we restrict parcel and region settings to full-perm inventory
  485. // settings ? This does not seem to be the case in LL's viewer-eep code, but
  486. // what is LL's actual policy on it ??? HB
  487. mCanSave = true;
  488. const LLPermissions& perms = mInventoryItem->getPermissions();
  489. mCanCopy = perms.allowCopyBy(gAgentID);
  490. mCanModify = perms.allowModifyBy(gAgentID);
  491. mCanTransfer = perms.allowTransferBy(gAgentID);
  492. mEditPanel->setEnabled(false);
  493. LLHandle<LLFloater> handle = getHandle();
  494. LLEnvSettingsBase::getSettingsAsset(asset_id,
  495. [handle](LLUUID id,
  496. LLSettingsBase::ptr_t settings,
  497. S32 status, LLExtStat)
  498. {
  499. HBFloaterEditEnvSettings* self =
  500. (HBFloaterEditEnvSettings*)handle.get();
  501. if (self)
  502. {
  503. self->onAssetLoaded(id,
  504. settings,
  505. status);
  506. }
  507. });
  508. }
  509. void HBFloaterEditEnvSettings::loadDefaultSettings()
  510. {
  511. if (mInventoryItem || mInventoryId.notNull())
  512. {
  513. llwarns << "A settings asset is alreadly loaded. Aborting." << llendl;
  514. return;
  515. }
  516. LLUUID asset_id;
  517. switch (mSettingsType)
  518. {
  519. case LLSettingsType::ST_SKY:
  520. asset_id = LLSettingsSky::getDefaultAssetId();
  521. break;
  522. case LLSettingsType::ST_WATER:
  523. asset_id = LLSettingsWater::getDefaultAssetId();
  524. break;
  525. case LLSettingsType::ST_DAYCYCLE:
  526. asset_id = LLSettingsDay::getDefaultAssetId();
  527. default: // Cannot happen; just here to keep the compilers happy
  528. break;
  529. }
  530. LLHandle<LLFloater> handle = getHandle();
  531. LLEnvSettingsBase::getSettingsAsset(asset_id,
  532. [handle](LLUUID id,
  533. LLSettingsBase::ptr_t settings,
  534. S32 status, LLExtStat)
  535. {
  536. HBFloaterEditEnvSettings* self =
  537. (HBFloaterEditEnvSettings*)handle.get();
  538. if (self)
  539. {
  540. self->onAssetLoaded(id,
  541. settings,
  542. status);
  543. }
  544. });
  545. }
  546. void HBFloaterEditEnvSettings::onAssetLoaded(const LLUUID& asset_id,
  547. LLSettingsBase::ptr_t settings,
  548. S32 status)
  549. {
  550. if (mInventoryItem && mInventoryItem->getAssetUUID() != asset_id)
  551. {
  552. llwarns << "Ignoring stale callback for asset Id: " << asset_id
  553. << llendl;
  554. return;
  555. }
  556. if (!settings || status)
  557. {
  558. gNotifications.add("CantFindInvItem");
  559. setDirty(false);
  560. close();
  561. return;
  562. }
  563. if (mInventoryItem)
  564. {
  565. settings->setName(mInventoryItem->getName());
  566. }
  567. bool land_context =
  568. mEditPanel->getEditContext() >= LLPanelEnvSettings::CONTEXT_PARCEL;
  569. // Forget the inventory item when editing parcel or region settings
  570. if (land_context)
  571. {
  572. mInventoryItem = NULL;
  573. }
  574. if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE))
  575. {
  576. mCanSave = mCanCopy = mCanModify = mCanTransfer = false;
  577. }
  578. else
  579. {
  580. if (mCanCopy)
  581. {
  582. settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
  583. }
  584. else
  585. {
  586. settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
  587. }
  588. if (mCanModify || land_context)
  589. {
  590. settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
  591. }
  592. else
  593. {
  594. settings->setFlag(LLSettingsBase::FLAG_NOMOD);
  595. }
  596. if (mCanTransfer)
  597. {
  598. settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
  599. }
  600. else
  601. {
  602. settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
  603. }
  604. }
  605. setSettings(settings);
  606. if (land_context)
  607. {
  608. // Set dirty since we just changed the edited settings from the
  609. // parcel/region current settings.
  610. setDirty();
  611. }
  612. gEnvironment.updateEnvironment(LLEnvironment::TRANSITION_FAST);
  613. }
  614. void HBFloaterEditEnvSettings::setSettings(const LLSettingsBase::ptr_t& settings)
  615. {
  616. mEditPanel->setSettings(settings);
  617. mCanSave = !settings->getFlag(LLSettingsBase::FLAG_NOSAVE);
  618. if (mCanSave)
  619. {
  620. mCanCopy = !settings->getFlag(LLSettingsBase::FLAG_NOCOPY);
  621. mCanModify = !settings->getFlag(LLSettingsBase::FLAG_NOMOD);
  622. mCanTransfer = !settings->getFlag(LLSettingsBase::FLAG_NOTRANS);
  623. }
  624. else
  625. {
  626. mCanCopy = mCanModify = mCanTransfer = false;
  627. }
  628. refresh();
  629. }
  630. void HBFloaterEditEnvSettings::updateEditEnvironment()
  631. {
  632. mEditPanel->updateEditEnvironment();
  633. }
  634. void HBFloaterEditEnvSettings::doApplyCreateNewInventory(const std::string& settings_name,
  635. const LLSettingsBase::ptr_t& settings)
  636. {
  637. LLHandle<LLFloater> handle = getHandle();
  638. if (mInventoryItem)
  639. {
  640. const LLUUID& parent_id = mInventoryItem->getParentUUID();
  641. U32 permission = mInventoryItem->getPermissions().getMaskNextOwner();
  642. LLEnvSettingsBase::createInventoryItem(settings, permission, parent_id,
  643. settings_name,
  644. [handle](LLUUID, LLUUID inv_id,
  645. LLUUID, LLSD results)
  646. {
  647. HBFloaterEditEnvSettings* self =
  648. (HBFloaterEditEnvSettings*)handle.get();
  649. if (self)
  650. {
  651. self->onInventoryCreated(inv_id,
  652. results);
  653. }
  654. });
  655. }
  656. else
  657. {
  658. const LLUUID& folder_id =
  659. gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
  660. LLEnvSettingsBase::createInventoryItem(settings, folder_id,
  661. settings_name,
  662. [handle](LLUUID, LLUUID inv_id,
  663. LLUUID, LLSD results)
  664. {
  665. HBFloaterEditEnvSettings* self =
  666. (HBFloaterEditEnvSettings*)handle.get();
  667. if (self)
  668. {
  669. self->onInventoryCreated(inv_id,
  670. results);
  671. }
  672. });
  673. }
  674. }
  675. void HBFloaterEditEnvSettings::doApplyUpdateInventory(const LLSettingsBase::ptr_t& settings)
  676. {
  677. LLHandle<LLFloater> handle = getHandle();
  678. if (mInventoryId.isNull())
  679. {
  680. const LLUUID& folder_id =
  681. gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
  682. LLEnvSettingsBase::createInventoryItem(settings, folder_id, "",
  683. [handle](LLUUID, LLUUID inv_id,
  684. LLUUID, LLSD results)
  685. {
  686. HBFloaterEditEnvSettings* self =
  687. (HBFloaterEditEnvSettings*)handle.get();
  688. if (self)
  689. {
  690. self->onInventoryCreated(inv_id,
  691. results);
  692. }
  693. });
  694. }
  695. else
  696. {
  697. LLEnvSettingsBase::updateInventoryItem(settings, mInventoryId,
  698. [handle](LLUUID, LLUUID inv_id,
  699. LLUUID, LLSD)
  700. {
  701. HBFloaterEditEnvSettings* self =
  702. (HBFloaterEditEnvSettings*)handle.get();
  703. if (self)
  704. {
  705. self->onInventoryUpdated(inv_id);
  706. }
  707. });
  708. }
  709. }
  710. void HBFloaterEditEnvSettings::onInventoryCreated(const LLUUID& inv_id,
  711. bool copied)
  712. {
  713. if (mInventoryItem)
  714. {
  715. const LLPermissions& perms = mInventoryItem->getPermissions();
  716. LLViewerInventoryItem* created_itemp = gInventory.getItem(inv_id);
  717. if (created_itemp)
  718. {
  719. created_itemp->setPermissions(perms);
  720. created_itemp->updateServer(false);
  721. }
  722. else
  723. {
  724. llwarns << "Cound not find the newly created inventory item, Id: "
  725. << inv_id << llendl;
  726. }
  727. }
  728. loadInventoryItem(inv_id, copied ? "SettingsCopied" : "SettingsCreated");
  729. setFocus(true);
  730. }
  731. void HBFloaterEditEnvSettings::onInventoryCreated(const LLUUID& inv_id,
  732. const LLSD& results)
  733. {
  734. if (inv_id.notNull() && results.has("success") &&
  735. results["success"].asBoolean())
  736. {
  737. onInventoryCreated(inv_id);
  738. }
  739. else
  740. {
  741. gNotifications.add("CantCreateInventory");
  742. }
  743. }
  744. void HBFloaterEditEnvSettings::onInventoryUpdated(const LLUUID& inv_id)
  745. {
  746. if (inv_id != mInventoryId)
  747. {
  748. loadInventoryItem(inv_id, "SettingsCreated");
  749. }
  750. else
  751. {
  752. // No need to reload settings data, but we need to reset the dirty flag
  753. setDirty(false);
  754. }
  755. }
  756. void HBFloaterEditEnvSettings::importFromFile(const std::string& filename)
  757. {
  758. LLSD messages;
  759. switch (mSettingsType)
  760. {
  761. case LLSettingsType::ST_SKY:
  762. {
  763. LLSettingsSky::ptr_t skyp =
  764. LLEnvironment::createSkyFromLegacyPreset(filename, messages);
  765. if (!skyp)
  766. {
  767. gNotifications.add("WLImportFail", messages);
  768. return;
  769. }
  770. loadInventoryItem(LLUUID::null);
  771. gEnvironment.setEnvironment(LLEnvironment::ENV_EDIT, skyp);
  772. setSettings(skyp);
  773. setDirty();
  774. break;
  775. }
  776. case LLSettingsType::ST_WATER:
  777. {
  778. LLSettingsWater::ptr_t waterp =
  779. LLEnvironment::createWaterFromLegacyPreset(filename, messages);
  780. if (!waterp)
  781. {
  782. gNotifications.add("WLImportFail", messages);
  783. return;
  784. }
  785. loadInventoryItem(LLUUID::null);
  786. gEnvironment.setEnvironment(LLEnvironment::ENV_EDIT, waterp);
  787. setSettings(waterp);
  788. setDirty();
  789. break;
  790. }
  791. case LLSettingsType::ST_DAYCYCLE:
  792. {
  793. LLSettingsDay::ptr_t dayp =
  794. LLEnvironment::createDayCycleFromLegacyPreset(filename,
  795. messages);
  796. if (!dayp)
  797. {
  798. gNotifications.add("WLImportFail", messages);
  799. return;
  800. }
  801. loadInventoryItem(LLUUID::null);
  802. gEnvironment.setEnvironment(LLEnvironment::ENV_EDIT, dayp);
  803. setSettings(dayp);
  804. setDirty();
  805. break;
  806. }
  807. default: // Should never happen...
  808. return;
  809. }
  810. gEnvironment.updateEnvironment(LLEnvironment::TRANSITION_FAST, true);
  811. refresh();
  812. setFocus(true);
  813. }
  814. //static
  815. void HBFloaterEditEnvSettings::onNameChanged(LLUICtrl*, void* userdata)
  816. {
  817. HBFloaterEditEnvSettings* self = (HBFloaterEditEnvSettings*)userdata;
  818. if (self && self->mEditPanel->settingsValid())
  819. {
  820. self->mEditPanel->setSettingsName(self->mNameEditor->getText());
  821. self->setDirty();
  822. }
  823. }
  824. static void inv_items_picker_cb(const std::vector<std::string>&,
  825. const uuid_vec_t& ids, void* userdata, bool)
  826. {
  827. HBFloaterEditEnvSettings* floaterp = (HBFloaterEditEnvSettings*)userdata;
  828. if (floaterp && !ids.empty())
  829. {
  830. floaterp->loadInventoryItem(ids[0]);
  831. }
  832. }
  833. static void load_confirm_cb(const LLSD& notification, const LLSD& response,
  834. S32 sub_type, void* data)
  835. {
  836. if (data && LLNotification::getSelectedOption(notification, response) == 0)
  837. {
  838. HBFloaterInvItemsPicker* pickerp =
  839. new HBFloaterInvItemsPicker((LLView*)data, inv_items_picker_cb,
  840. data);
  841. if (pickerp)
  842. {
  843. pickerp->setExcludeLibrary();
  844. pickerp->setAssetType(LLAssetType::AT_SETTINGS, sub_type);
  845. }
  846. }
  847. }
  848. //static
  849. void HBFloaterEditEnvSettings::onButtonLoad(void* userdata)
  850. {
  851. HBFloaterEditEnvSettings* self = (HBFloaterEditEnvSettings*)userdata;
  852. if (self)
  853. {
  854. S32 sub_type = self->mSettingsType;
  855. if (self->isDirty())
  856. {
  857. gNotifications.add("SettingsConfirmLoss", LLSD(), LLSD(),
  858. boost::bind(&load_confirm_cb, _1, _2, sub_type,
  859. self));
  860. return;
  861. }
  862. HBFloaterInvItemsPicker* pickerp =
  863. new HBFloaterInvItemsPicker(self, inv_items_picker_cb, self);
  864. if (pickerp)
  865. {
  866. pickerp->setExcludeLibrary();
  867. pickerp->setAssetType(LLAssetType::AT_SETTINGS, sub_type);
  868. }
  869. }
  870. }
  871. static void do_import_cb(HBFileSelector::ELoadFilter, std::string& filename,
  872. void* userdata)
  873. {
  874. HBFloaterEditEnvSettings* floaterp = (HBFloaterEditEnvSettings*)userdata;
  875. if (floaterp && !filename.empty())
  876. {
  877. floaterp->importFromFile(filename);
  878. }
  879. }
  880. static void import_confirm_cb(const LLSD& notification, const LLSD& response,
  881. void* userdata)
  882. {
  883. if (LLNotification::getSelectedOption(notification, response) == 0)
  884. {
  885. HBFileSelector::loadFile(HBFileSelector::FFLOAD_XML, do_import_cb,
  886. userdata);
  887. }
  888. }
  889. //static
  890. void HBFloaterEditEnvSettings::onButtonImport(void* userdata)
  891. {
  892. HBFloaterEditEnvSettings* self = (HBFloaterEditEnvSettings*)userdata;
  893. if (!self) return; // Paranoia
  894. if (self->isDirty())
  895. {
  896. gNotifications.add("SettingsConfirmLoss", LLSD(), LLSD(),
  897. boost::bind(&import_confirm_cb, _1, _2, userdata));
  898. }
  899. else
  900. {
  901. HBFileSelector::loadFile(HBFileSelector::FFLOAD_XML, do_import_cb,
  902. userdata);
  903. }
  904. }
  905. //static
  906. void HBFloaterEditEnvSettings::onButtonApply(LLUICtrl* ctrl, void* userdata)
  907. {
  908. HBFloaterEditEnvSettings* self = (HBFloaterEditEnvSettings*)userdata;
  909. if (!self || !ctrl || !self->mEditPanel->settingsValid()) return;
  910. if (self->mInventoryId.notNull() && self->mInventoryItem &&
  911. gInventory.getItem(self->mInventoryId) != self->mInventoryItem)
  912. {
  913. LLSD args;
  914. args["MESSAGE"] = self->getString("inventory_gone");
  915. gNotifications.add("GenericAlert", args);
  916. self->setDirty(false);
  917. self->close();
  918. return;
  919. }
  920. U32 flags = 0;
  921. if (self->mInventoryItem)
  922. {
  923. const LLPermissions& perms = self->mInventoryItem->getPermissions();
  924. if (!perms.allowModifyBy(gAgentID))
  925. {
  926. flags |= LLSettingsBase::FLAG_NOMOD;
  927. }
  928. if (!perms.allowTransferBy(gAgentID))
  929. {
  930. flags |= LLSettingsBase::FLAG_NOTRANS;
  931. }
  932. }
  933. std::string operation = ctrl->getValue().asString();
  934. if (operation == "apply_parcel")
  935. {
  936. if (!self->mInventoryItem || self->isDirty())
  937. {
  938. gNotifications.add("SaveSettingsFirst");
  939. return;
  940. }
  941. LLParcel* parcel = gViewerParcelMgr.getSelectedOrAgentParcel();
  942. if (!parcel || parcel->getLocalID() == INVALID_PARCEL_ID ||
  943. !LLEnvironment::canAgentUpdateParcelEnvironment(parcel))
  944. {
  945. gNotifications.add("WLParcelApplyFail");
  946. return;
  947. }
  948. gEnvironment.updateParcel(parcel->getLocalID(),
  949. self->mInventoryItem->getAssetUUID(),
  950. self->mInventoryItem->getName(),
  951. LLEnvironment::NO_TRACK, -1, -1, flags);
  952. self->mEditPanel->updateParcel(parcel->getLocalID());
  953. }
  954. else if (operation == "apply_region")
  955. {
  956. if (!self->mInventoryItem || self->isDirty())
  957. {
  958. gNotifications.add("SaveSettingsFirst");
  959. return;
  960. }
  961. if (!LLEnvironment::canAgentUpdateRegionEnvironment())
  962. {
  963. LLSD args;
  964. args["FAIL_REASON"] = LLTrans::getString("no_permission");
  965. gNotifications.add("WLRegionApplyFail", args);
  966. return;
  967. }
  968. gEnvironment.updateRegion(self->mInventoryItem->getAssetUUID(),
  969. self->mInventoryItem->getName(),
  970. LLEnvironment::NO_TRACK, -1, -1, flags);
  971. self->mEditPanel->updateRegion();
  972. }
  973. else // "apply_local" in pull-down list or direct click on the button
  974. {
  975. self->mEditPanel->updateLocal();
  976. }
  977. }
  978. //static
  979. void HBFloaterEditEnvSettings::onButtonSave(void* userdata)
  980. {
  981. HBFloaterEditEnvSettings* self = (HBFloaterEditEnvSettings*)userdata;
  982. if (!self || !self->mEditPanel->settingsValid()) return;
  983. LLSD args;
  984. if (self->mEditPanel->hasLocalTextures(args))
  985. {
  986. gNotifications.add("WLLocalTextureFixedBlock", args);
  987. return;
  988. }
  989. // If we are editing parcel or region settings, call any configured
  990. // callback and close.
  991. LLPanelEnvSettings::EEditContext ctx = self->mEditPanel->getEditContext();
  992. if (ctx >= LLPanelEnvSettings::CONTEXT_PARCEL)
  993. {
  994. if (self->mCommitSignal.empty())
  995. {
  996. llwarns << "No active callback found for this "
  997. << (ctx == LLPanelEnvSettings::CONTEXT_PARCEL ? "parcel"
  998. : "region")
  999. << " update. Changes are lost." << llendl;
  1000. }
  1001. else
  1002. {
  1003. self->mCommitSignal(self->mEditPanel->getSettingsClone());
  1004. }
  1005. self->setDirty(false);
  1006. self->close();
  1007. return;
  1008. }
  1009. if (!gAgent.hasInventorySettings())
  1010. {
  1011. return;
  1012. }
  1013. if (self->mInventoryId.notNull() && self->mInventoryItem &&
  1014. gInventory.getItem(self->mInventoryId) != self->mInventoryItem)
  1015. {
  1016. args["MESSAGE"] = self->getString("inventory_gone");
  1017. gNotifications.add("GenericAlert", args);
  1018. self->setDirty(false);
  1019. self->close();
  1020. return;
  1021. }
  1022. if (!self->mCanModify)
  1023. {
  1024. args["MESSAGE"] = self->getString("no_mod_settings");
  1025. gNotifications.add("GenericAlert", args);
  1026. return;
  1027. }
  1028. self->doApplyUpdateInventory(self->mEditPanel->getSettingsClone());
  1029. }
  1030. //static
  1031. void HBFloaterEditEnvSettings::onButtonSaveAsNew(void* userdata)
  1032. {
  1033. HBFloaterEditEnvSettings* self = (HBFloaterEditEnvSettings*)userdata;
  1034. if (!self || !self->mEditPanel->settingsValid()) return;
  1035. if (!gAgent.hasInventorySettings())
  1036. {
  1037. return;
  1038. }
  1039. if (self->mInventoryId.notNull() && self->mInventoryItem &&
  1040. gInventory.getItem(self->mInventoryId) != self->mInventoryItem)
  1041. {
  1042. LLSD args;
  1043. args["MESSAGE"] = self->getString("inventory_gone");
  1044. gNotifications.add("GenericAlert", args);
  1045. self->setDirty(false);
  1046. self->close();
  1047. return;
  1048. }
  1049. LLSD args;
  1050. if (!self->mCanCopy)
  1051. {
  1052. args["MESSAGE"] = self->getString("no_copy_settings");
  1053. gNotifications.add("GenericAlert", args);
  1054. return;
  1055. }
  1056. if (self->mEditPanel->hasLocalTextures(args))
  1057. {
  1058. if (self->mSettingsType == LLSettingsType::ST_DAYCYCLE)
  1059. {
  1060. gNotifications.add("WLLocalTextureDayBlock", args);
  1061. }
  1062. else
  1063. {
  1064. gNotifications.add("WLLocalTextureFixedBlock", args);
  1065. }
  1066. return;
  1067. }
  1068. LLViewerInventoryItem* itemp = self->mInventoryItem;
  1069. if (!itemp)
  1070. {
  1071. if (!self->mCanModify)
  1072. {
  1073. gNotifications.add("CantCreateInventory");
  1074. return;
  1075. }
  1076. self->doApplyCreateNewInventory(self->mEditPanel->getSettingsName(),
  1077. self->mEditPanel->getSettingsClone());
  1078. return;
  1079. }
  1080. const LLUUID& marketplace_id =
  1081. gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS,
  1082. false);
  1083. const LLUUID& library_id = gInventory.getLibraryRootFolderID();
  1084. LLUUID parent_id = itemp->getParentUUID();
  1085. if (gInventory.isObjectDescendentOf(itemp->getUUID(), marketplace_id) ||
  1086. gInventory.isObjectDescendentOf(itemp->getUUID(), library_id))
  1087. {
  1088. parent_id =
  1089. gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
  1090. }
  1091. // Create a new name for the settings inventory item. We try and keep track
  1092. // of former versions with the same base name, and incerement the version
  1093. // each time.
  1094. std::string name = self->mEditPanel->getSettingsName();
  1095. if (!self->mOriginalName.empty() &&
  1096. name == self->mOriginalName + llformat(" %d", self->mSaveAsNewCounter))
  1097. {
  1098. name = self->mOriginalName +
  1099. llformat(" %d", ++self->mSaveAsNewCounter);
  1100. }
  1101. else
  1102. {
  1103. self->mSaveAsNewCounter = 1;
  1104. self->mOriginalName = name;
  1105. name += " 1";
  1106. }
  1107. LLPointer<LLInventoryCallback> cb =
  1108. new HBSettingsCopiedCallback(self->getHandle());
  1109. copy_inventory_item(itemp->getPermissions().getOwner(), itemp->getUUID(),
  1110. parent_id, name, cb);
  1111. }
  1112. //static
  1113. void HBFloaterEditEnvSettings::onButtonCancel(void* userdata)
  1114. {
  1115. HBFloaterEditEnvSettings* self = (HBFloaterEditEnvSettings*)userdata;
  1116. if (self) // Paranoia
  1117. {
  1118. self->close();
  1119. }
  1120. }
  1121. ///////////////////////////////////////////////////////////////////////////////
  1122. // HBFloaterLocalEnv class
  1123. ///////////////////////////////////////////////////////////////////////////////
  1124. constexpr S32 FLOATER_LOCAL_ENV_UPDATE = -2;
  1125. //static
  1126. void HBFloaterLocalEnv::closeInstance()
  1127. {
  1128. HBFloaterLocalEnv* self = HBFloaterLocalEnv::findInstance();
  1129. if (self)
  1130. {
  1131. self->close();
  1132. }
  1133. }
  1134. //static
  1135. void* HBFloaterLocalEnv::createSkySettingsPanel(void* userdata)
  1136. {
  1137. HBFloaterLocalEnv* self = (HBFloaterLocalEnv*)userdata;
  1138. self->mEditSkyPanel = new LLPanelEnvSettingsSky();
  1139. return self->mEditSkyPanel;
  1140. }
  1141. //static
  1142. void* HBFloaterLocalEnv::createWaterSettingsPanel(void* userdata)
  1143. {
  1144. HBFloaterLocalEnv* self = (HBFloaterLocalEnv*)userdata;
  1145. self->mEditWaterPanel = new LLPanelEnvSettingsWater();
  1146. return self->mEditWaterPanel;
  1147. }
  1148. HBFloaterLocalEnv::HBFloaterLocalEnv(const LLSD&)
  1149. {
  1150. LLCallbackMap::map_t factory_map;
  1151. factory_map["sky_panel"] = LLCallbackMap(createSkySettingsPanel, this);
  1152. factory_map["water_panel"] = LLCallbackMap(createWaterSettingsPanel, this);
  1153. LLUICtrlFactory::getInstance()->buildFloater(this, "floater_local_env.xml",
  1154. &factory_map);
  1155. }
  1156. //virtual
  1157. bool HBFloaterLocalEnv::postBuild()
  1158. {
  1159. mResetBtn = getChild<LLButton>("btn_reset");
  1160. mResetBtn->setClickedCallback(onButtonReset, this);
  1161. mFixedTimeCheck = getChild<LLCheckBoxCtrl>("fixed_time_check");
  1162. mFixedTimeCheck->setCommitCallback(onCheckFixedTime);
  1163. mFixedTimeCheck->setCallbackUserData(this);
  1164. mFixedTimeSlider = getChild<LLSliderCtrl>("fixed_time_slider");
  1165. mFixedTimeSlider->setCommitCallback(onCommitFixedTime);
  1166. mFixedTimeSlider->setCallbackUserData(this);
  1167. childSetAction("btn_close", onButtonClose, this);
  1168. gSavedSettings.setBool("UseLocalEnvironment", true);
  1169. captureCurrentEnvironment();
  1170. mEventConnection = gEnvironment.setEnvironmentChanged(
  1171. [this](LLEnvironment::EEnvSelection env,
  1172. S32 version)
  1173. {
  1174. if (env == LLEnvironment::ENV_LOCAL &&
  1175. version != FLOATER_LOCAL_ENV_UPDATE)
  1176. {
  1177. captureCurrentEnvironment();
  1178. }
  1179. });
  1180. return true;
  1181. }
  1182. //virtual
  1183. void HBFloaterLocalEnv::onClose(bool app_quitting)
  1184. {
  1185. if (mEventConnection.connected())
  1186. {
  1187. mEventConnection.disconnect();
  1188. }
  1189. mLiveSky.reset();
  1190. mLiveWater.reset();
  1191. LLFloater::onClose(app_quitting);
  1192. }
  1193. //virtual
  1194. void HBFloaterLocalEnv::refresh()
  1195. {
  1196. bool enabled = mLiveSky && mLiveWater;
  1197. mResetBtn->setEnabled(enabled);
  1198. mEditSkyPanel->setCanEdit(enabled);
  1199. mEditWaterPanel->setCanEdit(enabled);
  1200. }
  1201. //MK
  1202. //virtual
  1203. void HBFloaterLocalEnv::draw()
  1204. {
  1205. // Fast enough that it can be kept here
  1206. if (gRLenabled && gRLInterface.mContainsSetenv)
  1207. {
  1208. close();
  1209. return;
  1210. }
  1211. LLFloater::draw();
  1212. }
  1213. //mk
  1214. void HBFloaterLocalEnv::captureCurrentEnvironment()
  1215. {
  1216. constexpr LLEnvironment::EEnvSelection PARCEL = LLEnvironment::ENV_PARCEL;
  1217. constexpr LLEnvironment::EEnvSelection LOCAL = LLEnvironment::ENV_LOCAL;
  1218. bool update_local = true;
  1219. if (!gEnvironment.hasEnvironment(LOCAL))
  1220. {
  1221. mLiveSky =
  1222. gEnvironment.getEnvironmentFixedSky(PARCEL, true)->buildClone();
  1223. mLiveWater =
  1224. gEnvironment.getEnvironmentFixedWater(PARCEL, true)->buildClone();
  1225. }
  1226. else if (gEnvironment.getEnvironmentDay(LOCAL))
  1227. {
  1228. // We have a full day cycle in the local environment: freeze the sky.
  1229. mLiveSky = gEnvironment.getEnvironmentFixedSky(LOCAL)->buildClone();
  1230. mLiveWater =
  1231. gEnvironment.getEnvironmentFixedWater(LOCAL)->buildClone();
  1232. }
  1233. else
  1234. {
  1235. // Otherwise we can just use the sky.
  1236. mLiveSky = gEnvironment.getEnvironmentFixedSky(LOCAL);
  1237. mLiveWater = gEnvironment.getEnvironmentFixedWater(LOCAL);
  1238. update_local = false;
  1239. }
  1240. mEditSkyPanel->setSettings(mLiveSky);
  1241. mEditWaterPanel->setSettings(mLiveWater);
  1242. if (update_local)
  1243. {
  1244. gEnvironment.setEnvironment(LOCAL, mLiveSky, FLOATER_LOCAL_ENV_UPDATE);
  1245. gEnvironment.setEnvironment(LOCAL, mLiveWater,
  1246. FLOATER_LOCAL_ENV_UPDATE);
  1247. }
  1248. gEnvironment.setSelectedEnvironment(LOCAL);
  1249. gEnvironment.setCurrentEnvironmentSelection(LOCAL);
  1250. gEnvironment.updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
  1251. refresh();
  1252. }
  1253. //static
  1254. void HBFloaterLocalEnv::onCheckFixedTime(LLUICtrl*, void* userdata)
  1255. {
  1256. HBFloaterLocalEnv* self = (HBFloaterLocalEnv*)userdata;
  1257. if (self)
  1258. {
  1259. bool checked = self->mFixedTimeCheck->get();
  1260. self->mFixedTimeCheck->setEnabled(!checked);
  1261. self->mFixedTimeSlider->setEnabled(checked);
  1262. }
  1263. }
  1264. //static
  1265. void HBFloaterLocalEnv::onCommitFixedTime(LLUICtrl*, void* userdata)
  1266. {
  1267. HBFloaterLocalEnv* self = (HBFloaterLocalEnv*)userdata;
  1268. if (self)
  1269. {
  1270. gEnvironment.setFixedTimeOfDay(self->mFixedTimeSlider->getValueF32());
  1271. }
  1272. }
  1273. //static
  1274. void HBFloaterLocalEnv::onButtonReset(void* userdata)
  1275. {
  1276. HBFloaterLocalEnv* self = (HBFloaterLocalEnv*)userdata;
  1277. if (self)
  1278. {
  1279. self->mFixedTimeCheck->set(false);
  1280. self->mFixedTimeCheck->setEnabled(true);
  1281. self->mFixedTimeSlider->setEnabled(false);
  1282. gEnvironment.clearEnvironment(LLEnvironment::ENV_LOCAL);
  1283. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
  1284. gEnvironment.setCurrentEnvironmentSelection(LLEnvironment::ENV_LOCAL);
  1285. gEnvironment.updateEnvironment();
  1286. }
  1287. }
  1288. //static
  1289. void HBFloaterLocalEnv::onButtonClose(void* userdata)
  1290. {
  1291. HBFloaterLocalEnv* self = (HBFloaterLocalEnv*)userdata;
  1292. if (self)
  1293. {
  1294. self->close();
  1295. }
  1296. }