llcontrol.cpp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469
  1. /**
  2. * @file llcontrol.cpp
  3. * @brief Holds global state for viewer.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #include <iostream>
  34. #include <fstream>
  35. #include <algorithm>
  36. #include "llcontrol.h"
  37. #include "llstl.h"
  38. #include "llstring.h"
  39. #include "llvector3.h"
  40. #include "llvector3d.h"
  41. #include "llcolor4u.h"
  42. #include "llcolor4.h"
  43. #include "llcolor3.h"
  44. #include "llrect.h"
  45. #include "llxmltree.h"
  46. #include "llsdserialize.h"
  47. #if LL_DEBUG
  48. #define CONTROL_ERRS llerrs
  49. #else
  50. #define CONTROL_ERRS llwarns
  51. #endif
  52. template<> eControlType get_control_type<U32>();
  53. template<> eControlType get_control_type<S32>();
  54. template<> eControlType get_control_type<F32>();
  55. template<> eControlType get_control_type<bool>();
  56. template<> eControlType get_control_type<std::string>();
  57. template<> eControlType get_control_type<LLVector3>();
  58. template<> eControlType get_control_type<LLVector3d>();
  59. template<> eControlType get_control_type<LLRect>();
  60. template<> eControlType get_control_type<LLColor4>();
  61. template<> eControlType get_control_type<LLColor3>();
  62. template<> eControlType get_control_type<LLColor4U>();
  63. template<> eControlType get_control_type<LLSD>();
  64. template<> LLSD convert_to_llsd<U32>(const U32& in);
  65. template<> LLSD convert_to_llsd<LLVector3>(const LLVector3& in);
  66. template<> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in);
  67. template<> LLSD convert_to_llsd<LLRect>(const LLRect& in);
  68. template<> LLSD convert_to_llsd<LLColor4>(const LLColor4& in);
  69. template<> LLSD convert_to_llsd<LLColor3>(const LLColor3& in);
  70. template<> LLSD convert_to_llsd<LLColor4U>(const LLColor4U& in);
  71. template<> bool convert_from_llsd<bool>(const LLSD& sd, eControlType type,
  72. const char* control_name);
  73. template<> S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type,
  74. const char* control_name);
  75. template<> U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type,
  76. const char* control_name);
  77. template<> F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type,
  78. const char* control_name);
  79. template<> std::string convert_from_llsd<std::string>(const LLSD& sd,
  80. eControlType type,
  81. const char* control_name);
  82. template<> LLWString convert_from_llsd<LLWString>(const LLSD& sd,
  83. eControlType type,
  84. const char* control_name);
  85. template<> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd,
  86. eControlType type,
  87. const char* control_name);
  88. template<> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd,
  89. eControlType type,
  90. const char* control_name);
  91. template<> LLRect convert_from_llsd<LLRect>(const LLSD& sd,
  92. eControlType type,
  93. const char* control_name);
  94. template<> LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd,
  95. eControlType type,
  96. const char* control_name);
  97. template<> LLColor4U convert_from_llsd<LLColor4U>(const LLSD& sd,
  98. eControlType type,
  99. const char* control_name);
  100. template<> LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd,
  101. eControlType type,
  102. const char* control_name);
  103. template<> LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type,
  104. const char* control_name);
  105. // This defines the current version of the settings file
  106. constexpr S32 CURRENT_VERSION = 101;
  107. bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD& b)
  108. {
  109. bool result = false;
  110. switch (mType)
  111. {
  112. case TYPE_U32:
  113. case TYPE_S32:
  114. result = a.asInteger() == b.asInteger();
  115. break;
  116. case TYPE_BOOLEAN:
  117. result = a.asBoolean() == b.asBoolean();
  118. break;
  119. case TYPE_F32:
  120. result = a.asReal() == b.asReal();
  121. break;
  122. case TYPE_VEC3:
  123. case TYPE_VEC3D:
  124. result = LLVector3d(a) == LLVector3d(b);
  125. break;
  126. case TYPE_RECT:
  127. result = LLRect(a) == LLRect(b);
  128. break;
  129. case TYPE_COL4:
  130. result = LLColor4(a) == LLColor4(b);
  131. break;
  132. case TYPE_COL3:
  133. result = LLColor3(a) == LLColor3(b);
  134. break;
  135. case TYPE_COL4U:
  136. result = LLColor4U(a) == LLColor4U(b);
  137. break;
  138. case TYPE_STRING:
  139. result = a.asString() == b.asString();
  140. break;
  141. default:
  142. break;
  143. }
  144. return result;
  145. }
  146. LLControlVariable::LLControlVariable(const char* name, eControlType type,
  147. LLSD initial, const std::string& comment,
  148. bool persist, bool hide_from_user)
  149. : mName(name),
  150. mComment(comment),
  151. mType(type),
  152. mPersist(persist),
  153. mHideFromUser(hide_from_user)
  154. {
  155. if (mPersist && mComment.empty())
  156. {
  157. llerrs << "Must supply a comment for control " << mName << llendl;
  158. }
  159. // Push back versus setValue'ing here, since we don't want to call a signal
  160. // yet
  161. mValues.push_back(initial);
  162. }
  163. LLSD LLControlVariable::getComparableValue(const LLSD& value)
  164. {
  165. // *FIXME: the following is needed to make the LLSD::ImplString work with
  166. // boolean controls...
  167. LLSD storable_value;
  168. if (type() == TYPE_BOOLEAN && value.isString())
  169. {
  170. bool temp;
  171. if (LLStringUtil::convertToBool(value.asString(), temp))
  172. {
  173. storable_value = temp;
  174. }
  175. else
  176. {
  177. storable_value = false;
  178. }
  179. }
  180. else if (type() == TYPE_LLSD && value.isString())
  181. {
  182. LLPointer<LLSDNotationParser> parser = new LLSDNotationParser;
  183. LLSD result;
  184. std::stringstream value_stream(value.asString());
  185. if (parser->parse(value_stream, result,
  186. LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE)
  187. {
  188. storable_value = result;
  189. }
  190. else
  191. {
  192. storable_value = value;
  193. }
  194. }
  195. else
  196. {
  197. storable_value = value;
  198. }
  199. return storable_value;
  200. }
  201. void LLControlVariable::setValue(const LLSD& new_value, bool saved_value)
  202. {
  203. if (!mValidateSignal(this, new_value))
  204. {
  205. // Cannot set new value, exit
  206. return;
  207. }
  208. LLSD storable_value = getComparableValue(new_value);
  209. bool value_changed = !llsd_compare(getValue(), storable_value);
  210. if (saved_value)
  211. {
  212. // If we are going to save this value, return to default but do not
  213. // fire
  214. resetToDefault(false);
  215. if (!llsd_compare(mValues.back(), storable_value))
  216. {
  217. mValues.push_back(storable_value);
  218. }
  219. }
  220. else
  221. {
  222. // This is a unsaved value. It needs to reside at mValues[2] (or
  223. // greater). It must not affect the result of getSaveValue()
  224. if (!llsd_compare(mValues.back(), storable_value))
  225. {
  226. while (mValues.size() > 2)
  227. {
  228. // Remove any unsaved values.
  229. mValues.pop_back();
  230. }
  231. if (mValues.size() < 2)
  232. {
  233. // Add the default to the 'save' value.
  234. mValues.push_back(mValues[0]);
  235. }
  236. // Add the 'un-save' value.
  237. mValues.push_back(storable_value);
  238. }
  239. }
  240. if (value_changed)
  241. {
  242. mCommitSignal(this, storable_value);
  243. }
  244. }
  245. void LLControlVariable::setDefaultValue(const LLSD& value)
  246. {
  247. // Set the control variables value and make it
  248. // the default value. If the active value is changed,
  249. // send the signal.
  250. // *NOTE: Default values are not saved, only read.
  251. LLSD comparable_value = getComparableValue(value);
  252. bool value_changed = !llsd_compare(getValue(), comparable_value);
  253. resetToDefault(false);
  254. mValues[0] = comparable_value;
  255. if (value_changed)
  256. {
  257. firePropertyChanged();
  258. }
  259. }
  260. void LLControlVariable::setPersist(bool state)
  261. {
  262. mPersist = state;
  263. }
  264. void LLControlVariable::setHiddenFromUser(bool hide)
  265. {
  266. mHideFromUser = hide;
  267. }
  268. void LLControlVariable::setComment(const std::string& comment)
  269. {
  270. mComment = comment;
  271. }
  272. void LLControlVariable::resetToDefault(bool fire_signal)
  273. {
  274. //The first setting is always the default
  275. //Pop to it and fire off the listener
  276. while (mValues.size() > 1)
  277. {
  278. mValues.pop_back();
  279. }
  280. if (fire_signal)
  281. {
  282. firePropertyChanged();
  283. }
  284. }
  285. bool LLControlVariable::isSaveValueDefault()
  286. {
  287. return mValues.size() == 1 ||
  288. (mValues.size() > 1 && llsd_compare(mValues[1], mValues[0]));
  289. }
  290. LLSD LLControlVariable::getSaveValue(bool user_value) const
  291. {
  292. // The first level of the stack is default. We assume that the second level
  293. // is user preferences that should be saved
  294. return user_value && mValues.size() > 1 ? mValues[1] : mValues[0];
  295. }
  296. LLControlVariablePtr LLControlGroup::getControl(const char* name)
  297. {
  298. if (!name || !*name)
  299. {
  300. return LLControlVariablePtr();
  301. }
  302. ctrl_name_table_t::iterator iter = mNameTable.find(name);
  303. return iter == mNameTable.end() ? LLControlVariablePtr() : iter->second;
  304. }
  305. ////////////////////////////////////////////////////////////////////////////
  306. LLControlGroup::LLControlGroup(const std::string& name)
  307. : LLInstanceTracker<LLControlGroup, std::string>(name)
  308. {
  309. mTypeString[TYPE_U32] = "U32";
  310. mTypeString[TYPE_S32] = "S32";
  311. mTypeString[TYPE_F32] = "F32";
  312. mTypeString[TYPE_BOOLEAN] = "Boolean";
  313. mTypeString[TYPE_STRING] = "String";
  314. mTypeString[TYPE_VEC3] = "Vector3";
  315. mTypeString[TYPE_VEC3D] = "Vector3D";
  316. mTypeString[TYPE_RECT] = "Rect";
  317. mTypeString[TYPE_COL4] = "Color4";
  318. mTypeString[TYPE_COL3] = "Color3";
  319. mTypeString[TYPE_COL4U] = "Color4u";
  320. mTypeString[TYPE_LLSD] = "LLSD";
  321. }
  322. LLControlGroup::~LLControlGroup()
  323. {
  324. cleanup();
  325. }
  326. void LLControlGroup::cleanup()
  327. {
  328. mNameTable.clear();
  329. }
  330. eControlType LLControlGroup::typeStringToEnum(const std::string& typestr)
  331. {
  332. for (U32 i = 0; i < (U32)TYPE_COUNT; ++i)
  333. {
  334. if (mTypeString[i] == typestr)
  335. {
  336. return (eControlType)i;
  337. }
  338. }
  339. return (eControlType)-1;
  340. }
  341. std::string LLControlGroup::typeEnumToString(eControlType typeenum)
  342. {
  343. return mTypeString[typeenum];
  344. }
  345. LLControlVariable* LLControlGroup::declareControl(const char* name,
  346. eControlType type,
  347. const LLSD initial_val,
  348. const std::string& comment,
  349. bool persist,
  350. bool hide_from_user)
  351. {
  352. LLControlVariable* controlp = getControl(name);
  353. if (!controlp)
  354. {
  355. // If is does not yet exist, create the control and add it to the name
  356. // table
  357. controlp = new LLControlVariable(name, type, initial_val, comment,
  358. persist, hide_from_user);
  359. mNameTable.emplace(name, controlp);
  360. }
  361. // Sometimes we need to declare a control *after* it has been loaded from a
  362. // settings file.
  363. else if (persist && controlp->isType(type))
  364. {
  365. if (!controlp->llsd_compare(controlp->getDefault(), initial_val))
  366. {
  367. // Get the current value:
  368. LLSD cur_value = controlp->getValue();
  369. // Set the default to the declared value:
  370. controlp->setDefaultValue(initial_val);
  371. // Now set to the loaded value
  372. controlp->setValue(cur_value);
  373. }
  374. }
  375. else
  376. {
  377. llwarns << "Control named " << name
  378. << " already exists; ignoring new declaration." << llendl;
  379. }
  380. return controlp;
  381. }
  382. LLControlVariable* LLControlGroup::declareBool(const char* name,
  383. bool initial_val,
  384. const std::string& comment,
  385. bool persist)
  386. {
  387. return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist);
  388. }
  389. LLControlVariable* LLControlGroup::declareString(const char* name,
  390. const std::string& initial_val,
  391. const std::string& comment,
  392. bool persist)
  393. {
  394. return declareControl(name, TYPE_STRING, initial_val, comment, persist);
  395. }
  396. LLControlVariable* LLControlGroup::declareColor4U(const char* name,
  397. const LLColor4U& initial_val,
  398. const std::string& comment,
  399. bool persist)
  400. {
  401. return declareControl(name, TYPE_COL4U, initial_val.getValue(), comment,
  402. persist);
  403. }
  404. LLControlVariable* LLControlGroup::declareColor4(const char* name,
  405. const LLColor4& initial_val,
  406. const std::string& comment,
  407. bool persist)
  408. {
  409. return declareControl(name, TYPE_COL4, initial_val.getValue(), comment,
  410. persist);
  411. }
  412. LLControlVariable* LLControlGroup::declareLLSD(const char* name,
  413. const LLSD& initial_val,
  414. const std::string& comment,
  415. bool persist)
  416. {
  417. return declareControl(name, TYPE_LLSD, initial_val, comment, persist);
  418. }
  419. #if 0 // Not used
  420. LLControlVariable* LLControlGroup::declareU32(const char* name,
  421. U32 initial_val,
  422. const std::string& comment,
  423. bool persist)
  424. {
  425. return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment,
  426. persist);
  427. }
  428. LLControlVariable* LLControlGroup::declareS32(const char* name,
  429. S32 initial_val,
  430. const std::string& comment,
  431. bool persist)
  432. {
  433. return declareControl(name, TYPE_S32, initial_val, comment, persist);
  434. }
  435. LLControlVariable* LLControlGroup::declareF32(const char* name,
  436. F32 initial_val,
  437. const std::string& comment,
  438. bool persist)
  439. {
  440. return declareControl(name, TYPE_F32, initial_val, comment, persist);
  441. }
  442. LLControlVariable* LLControlGroup::declareVec3(const char* name,
  443. const LLVector3& initial_val,
  444. const std::string& comment,
  445. bool persist)
  446. {
  447. return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment,
  448. persist);
  449. }
  450. LLControlVariable* LLControlGroup::declareVec3d(const char* name,
  451. const LLVector3d& initial_val,
  452. const std::string& comment,
  453. bool persist)
  454. {
  455. return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment,
  456. persist);
  457. }
  458. LLControlVariable* LLControlGroup::declareRect(const char* name,
  459. const LLRect& initial_val,
  460. const std::string& comment,
  461. bool persist)
  462. {
  463. return declareControl(name, TYPE_RECT, initial_val.getValue(), comment,
  464. persist);
  465. }
  466. LLControlVariable* LLControlGroup::declareColor3(const char* name,
  467. const LLColor3& initial_val,
  468. const std::string& comment,
  469. bool persist)
  470. {
  471. return declareControl(name, TYPE_COL3, initial_val.getValue(), comment,
  472. persist);
  473. }
  474. #endif
  475. bool LLControlGroup::getBool(const char* name)
  476. {
  477. return get<bool>(name);
  478. }
  479. S32 LLControlGroup::getS32(const char* name)
  480. {
  481. return get<S32>(name);
  482. }
  483. U32 LLControlGroup::getU32(const char* name)
  484. {
  485. return get<U32>(name);
  486. }
  487. F32 LLControlGroup::getF32(const char* name)
  488. {
  489. return get<F32>(name);
  490. }
  491. std::string LLControlGroup::getString(const char* name)
  492. {
  493. return get<std::string>(name);
  494. }
  495. LLWString LLControlGroup::getWString(const char* name)
  496. {
  497. return get<LLWString>(name);
  498. }
  499. std::string LLControlGroup::getText(const char* name)
  500. {
  501. std::string utf8_string = getString(name);
  502. LLStringUtil::replaceChar(utf8_string, '^', '\n');
  503. LLStringUtil::replaceChar(utf8_string, '%', ' ');
  504. return (utf8_string);
  505. }
  506. LLVector3 LLControlGroup::getVector3(const char* name)
  507. {
  508. return get<LLVector3>(name);
  509. }
  510. LLVector3d LLControlGroup::getVector3d(const char* name)
  511. {
  512. return get<LLVector3d>(name);
  513. }
  514. LLRect LLControlGroup::getRect(const char* name)
  515. {
  516. return get<LLRect>(name);
  517. }
  518. LLColor4 LLControlGroup::getColor(const char* name)
  519. {
  520. LL_DEBUGS("GetControlCalls") << "Requested control: " << name << LL_ENDL;
  521. ctrl_name_table_t::const_iterator i = mNameTable.find(name);
  522. if (i != mNameTable.end())
  523. {
  524. LLControlVariable* controlp = i->second;
  525. switch (controlp->mType)
  526. {
  527. case TYPE_COL4:
  528. {
  529. return LLColor4(controlp->getValue());
  530. }
  531. case TYPE_COL4U:
  532. {
  533. return LLColor4(LLColor4U(controlp->getValue()));
  534. }
  535. default:
  536. {
  537. CONTROL_ERRS << "Control " << name << " not a color" << llendl;
  538. return LLColor4::white;
  539. }
  540. }
  541. }
  542. else
  543. {
  544. CONTROL_ERRS << "Invalid getColor control " << name << llendl;
  545. return LLColor4::white;
  546. }
  547. }
  548. LLColor4 LLControlGroup::getColor4(const char* name)
  549. {
  550. return get<LLColor4>(name);
  551. }
  552. LLColor4U LLControlGroup::getColor4U(const char* name)
  553. {
  554. return get<LLColor4U>(name);
  555. }
  556. LLColor3 LLControlGroup::getColor3(const char* name)
  557. {
  558. return get<LLColor3>(name);
  559. }
  560. LLSD LLControlGroup::getLLSD(const char* name)
  561. {
  562. return get<LLSD>(name);
  563. }
  564. bool LLControlGroup::controlExists(const char* name)
  565. {
  566. ctrl_name_table_t::iterator iter = mNameTable.find(name);
  567. return iter != mNameTable.end();
  568. }
  569. //-------------------------------------------------------------------
  570. // Set functions
  571. //-------------------------------------------------------------------
  572. void LLControlGroup::setBool(const char* name, bool val)
  573. {
  574. set(name, val);
  575. }
  576. void LLControlGroup::setS32(const char* name, S32 val)
  577. {
  578. set(name, val);
  579. }
  580. void LLControlGroup::setF32(const char* name, F32 val)
  581. {
  582. set(name, val);
  583. }
  584. void LLControlGroup::setU32(const char* name, U32 val)
  585. {
  586. set(name, val);
  587. }
  588. void LLControlGroup::setString(const char* name, const std::string& val)
  589. {
  590. set(name, val);
  591. }
  592. void LLControlGroup::setVector3(const char* name, const LLVector3& val)
  593. {
  594. set(name, val);
  595. }
  596. void LLControlGroup::setVector3d(const char* name, const LLVector3d& val)
  597. {
  598. set(name, val);
  599. }
  600. void LLControlGroup::setRect(const char* name, const LLRect& val)
  601. {
  602. set(name, val);
  603. }
  604. void LLControlGroup::setColor4(const char* name, const LLColor4& val)
  605. {
  606. set(name, val);
  607. }
  608. void LLControlGroup::setLLSD(const char* name, const LLSD& val)
  609. {
  610. set(name, val);
  611. }
  612. void LLControlGroup::setUntypedValue(const char* name, const LLSD& val)
  613. {
  614. if (!name || !*name)
  615. {
  616. return;
  617. }
  618. LLControlVariable* controlp = getControl(name);
  619. if (controlp)
  620. {
  621. controlp->setValue(val);
  622. }
  623. else
  624. {
  625. CONTROL_ERRS << "Invalid control " << name << llendl;
  626. }
  627. }
  628. //---------------------------------------------------------------
  629. // Load and save
  630. //---------------------------------------------------------------
  631. // Returns number of controls loaded, so 0 if failure
  632. U32 LLControlGroup::loadFromFileLegacy(const std::string& filename,
  633. bool require_declaration,
  634. eControlType declare_as)
  635. {
  636. std::string name;
  637. LLXmlTree xml_controls;
  638. if (!xml_controls.parseFile(filename))
  639. {
  640. llwarns << "Unable to open control file: " << filename << llendl;
  641. return 0;
  642. }
  643. LLXmlTreeNode* rootp = xml_controls.getRoot();
  644. if (!rootp || !rootp->hasAttribute("version"))
  645. {
  646. llwarns << "No valid settings header found in control file: "
  647. << filename << llendl;
  648. return 0;
  649. }
  650. U32 validitems = 0;
  651. S32 version;
  652. rootp->getAttributeS32("version", version);
  653. // Check file version
  654. if (version != CURRENT_VERSION)
  655. {
  656. llinfos << filename << " does not appear to be a version "
  657. << CURRENT_VERSION << " controls file" << llendl;
  658. return 0;
  659. }
  660. LLXmlTreeNode* child_nodep = rootp->getFirstChild();
  661. while (child_nodep)
  662. {
  663. name = child_nodep->getName();
  664. bool declared = controlExists(name.c_str());
  665. if (require_declaration && !declared)
  666. {
  667. // Declaration required, but this name not declared.
  668. // Complain about non-empty names.
  669. if (!name.empty())
  670. {
  671. // Read in to end of line
  672. llwarns << "Trying to set \"" << name
  673. << "\", setting doesn't exist." << llendl;
  674. }
  675. child_nodep = rootp->getNextChild();
  676. continue;
  677. }
  678. // Got an item. Load it up.
  679. // If not declared, assume it is a string
  680. if (!declared)
  681. {
  682. switch (declare_as)
  683. {
  684. case TYPE_COL4:
  685. declareColor4(name.c_str(), LLColor4::white,
  686. LLStringUtil::null, NO_PERSIST);
  687. break;
  688. case TYPE_COL4U:
  689. declareColor4U(name.c_str(), LLColor4U::white,
  690. LLStringUtil::null, NO_PERSIST);
  691. break;
  692. case TYPE_STRING:
  693. default:
  694. declareString(name.c_str(), LLStringUtil::null,
  695. LLStringUtil::null, NO_PERSIST);
  696. }
  697. }
  698. // Control name has been declared in code.
  699. LLControlVariable* controlp = getControl(name.c_str());
  700. llassert(controlp);
  701. switch (controlp->mType)
  702. {
  703. case TYPE_F32:
  704. {
  705. F32 initial = 0.f;
  706. child_nodep->getAttributeF32("value", initial);
  707. controlp->setValue(initial);
  708. controlp->setDefaultValue(initial);
  709. ++validitems;
  710. break;
  711. }
  712. case TYPE_S32:
  713. {
  714. S32 initial = 0;
  715. child_nodep->getAttributeS32("value", initial);
  716. controlp->setValue(initial);
  717. controlp->setDefaultValue(initial);
  718. ++validitems;
  719. break;
  720. }
  721. case TYPE_U32:
  722. {
  723. U32 initial = 0;
  724. child_nodep->getAttributeU32("value", initial);
  725. controlp->setValue((LLSD::Integer) initial);
  726. controlp->setDefaultValue((LLSD::Integer)initial);
  727. ++validitems;
  728. break;
  729. }
  730. case TYPE_BOOLEAN:
  731. {
  732. bool initial = false;
  733. child_nodep->getAttributeBool("value", initial);
  734. controlp->setValue(initial);
  735. controlp->setDefaultValue(initial);
  736. ++validitems;
  737. break;
  738. }
  739. case TYPE_STRING:
  740. {
  741. std::string string;
  742. child_nodep->getAttributeString("value", string);
  743. controlp->setValue(string);
  744. controlp->setDefaultValue(string);
  745. ++validitems;
  746. break;
  747. }
  748. case TYPE_VEC3:
  749. {
  750. LLVector3 vector;
  751. child_nodep->getAttributeVector3("value", vector);
  752. controlp->setValue(vector.getValue());
  753. controlp->setDefaultValue(vector.getValue());
  754. ++validitems;
  755. break;
  756. }
  757. case TYPE_VEC3D:
  758. {
  759. LLVector3d vector;
  760. child_nodep->getAttributeVector3d("value", vector);
  761. controlp->setValue(vector.getValue());
  762. controlp->setDefaultValue(vector.getValue());
  763. ++validitems;
  764. break;
  765. }
  766. case TYPE_RECT:
  767. {
  768. // RN: hack to support reading rectangles from a string
  769. std::string rect_string;
  770. child_nodep->getAttributeString("value", rect_string);
  771. std::istringstream istream(rect_string);
  772. S32 left, bottom, width, height;
  773. istream >> left >> bottom >> width >> height;
  774. LLRect rect;
  775. rect.setOriginAndSize(left, bottom, width, height);
  776. controlp->setValue(rect.getValue());
  777. controlp->setDefaultValue(rect.getValue());
  778. ++validitems;
  779. break;
  780. }
  781. case TYPE_COL4U:
  782. {
  783. LLColor4U color;
  784. child_nodep->getAttributeColor4U("value", color);
  785. controlp->setValue(color.getValue());
  786. controlp->setDefaultValue(color.getValue());
  787. ++validitems;
  788. break;
  789. }
  790. case TYPE_COL4:
  791. {
  792. LLColor4 color;
  793. child_nodep->getAttributeColor4("value", color);
  794. controlp->setValue(color.getValue());
  795. controlp->setDefaultValue(color.getValue());
  796. ++validitems;
  797. break;
  798. }
  799. case TYPE_COL3:
  800. {
  801. LLVector3 color;
  802. child_nodep->getAttributeVector3("value", color);
  803. controlp->setValue(LLColor3(color.mV).getValue());
  804. controlp->setDefaultValue(LLColor3(color.mV).getValue());
  805. ++validitems;
  806. break;
  807. }
  808. default:
  809. break;
  810. }
  811. child_nodep = rootp->getNextChild();
  812. }
  813. return validitems;
  814. }
  815. U32 LLControlGroup::saveToFile(const std::string& filename,
  816. bool nondefault_only,
  817. bool save_default)
  818. {
  819. LLSD settings;
  820. U32 num_saved = 0;
  821. for (ctrl_name_table_t::iterator iter = mNameTable.begin(),
  822. end = mNameTable.end();
  823. iter != end; ++iter)
  824. {
  825. LLControlVariable* controlp = iter->second;
  826. if (!controlp)
  827. {
  828. llwarns << "Tried to save invalid control: " << iter->first
  829. << llendl;
  830. }
  831. if (controlp && (save_default || controlp->isPersisted()))
  832. {
  833. if (!nondefault_only || !controlp->isSaveValueDefault())
  834. {
  835. settings[iter->first]["Comment"] = controlp->getComment();
  836. if (save_default)
  837. {
  838. settings[iter->first]["Persist"] =
  839. LLSD(controlp->isPersisted());
  840. if (controlp->isHiddenFromUser())
  841. {
  842. settings[iter->first]["HideFromEditor"] = LLSD(true);
  843. }
  844. }
  845. settings[iter->first]["Type"] =
  846. typeEnumToString(controlp->type());
  847. LLSD value = controlp->getSaveValue(!save_default);
  848. // Let's make sure we save the value as its actual type (which
  849. // might not be the case for booelans, integers and floats...):
  850. LLSD true_value;
  851. switch (controlp->type())
  852. {
  853. case TYPE_BOOLEAN:
  854. true_value = LLSD(value.asBoolean());
  855. break;
  856. case TYPE_U32:
  857. case TYPE_S32:
  858. true_value = LLSD(value.asInteger());
  859. break;
  860. case TYPE_F32:
  861. true_value = LLSD(value.asReal());
  862. break;
  863. default:
  864. true_value = value;
  865. }
  866. settings[iter->first]["Value"] = true_value;
  867. ++num_saved;
  868. }
  869. else
  870. {
  871. LL_DEBUGS("SaveSettings") << "Skipping " << controlp->getName()
  872. << LL_ENDL;
  873. }
  874. }
  875. }
  876. llofstream file(filename.c_str());
  877. if (file.is_open())
  878. {
  879. LLSDSerialize::toPrettyXML(settings, file);
  880. file.close();
  881. llinfos << "Saved to " << filename << llendl;
  882. }
  883. else
  884. {
  885. // This is a warning because sometime we want to use settings files
  886. // which cannot be written...
  887. llwarns << "Unable to open settings file: " << filename << llendl;
  888. return 0;
  889. }
  890. return num_saved;
  891. }
  892. U32 LLControlGroup::loadFromFile(const std::string& filename,
  893. bool set_default_values, bool save_values)
  894. {
  895. llifstream infile(filename.c_str());
  896. if (!infile.is_open())
  897. {
  898. llwarns << "Cannot find file " << filename << " to load." << llendl;
  899. return 0;
  900. }
  901. LLSD settings;
  902. if (LLSDSerialize::fromXML(settings, infile) == LLSDParser::PARSE_FAILURE)
  903. {
  904. infile.close();
  905. llwarns << "Unable to parse LLSD control file " << filename
  906. << ". Trying the legacy method." << llendl;
  907. return loadFromFileLegacy(filename, true, TYPE_STRING);
  908. }
  909. U32 validitems = 0;
  910. bool hide_from_editor = false;
  911. for (LLSD::map_const_iterator itr = settings.beginMap(),
  912. end = settings.endMap();
  913. itr != end; ++itr)
  914. {
  915. bool persist = true;
  916. const std::string& name = itr->first;
  917. const LLSD& control_map = itr->second;
  918. if (control_map.has("Persist"))
  919. {
  920. persist = control_map["Persist"].asInteger();
  921. }
  922. // Sometimes we want to use the settings system to provide cheap
  923. // persistence, but we do not want the settings themselves to be easily
  924. // manipulated in the UI because doing so can cause support problems.
  925. // So we have this option:
  926. if (control_map.has("HideFromEditor"))
  927. {
  928. hide_from_editor = control_map["HideFromEditor"].asInteger();
  929. }
  930. else
  931. {
  932. hide_from_editor = false;
  933. }
  934. // If the control exists just set the value from the input file.
  935. LLControlVariable* controlp = getControl(name.c_str());
  936. if (controlp)
  937. {
  938. if (set_default_values)
  939. {
  940. // Override all previously set properties of this control.
  941. // ... except for type. The types must match.
  942. eControlType new_type =
  943. typeStringToEnum(control_map["Type"].asString());
  944. if (controlp->isType(new_type))
  945. {
  946. controlp->setDefaultValue(control_map["Value"]);
  947. controlp->setPersist(persist);
  948. controlp->setHiddenFromUser(hide_from_editor);
  949. controlp->setComment(control_map["Comment"].asString());
  950. }
  951. else
  952. {
  953. llerrs << "Mismatched type of control variable '" << name
  954. << "' found while loading '" << filename << "'."
  955. << llendl;
  956. }
  957. }
  958. else if (controlp->isPersisted())
  959. {
  960. controlp->setValue(control_map["Value"], save_values);
  961. }
  962. // *NOTE: If not persisted and not setting defaults,
  963. // the value should not get loaded.
  964. }
  965. else
  966. {
  967. declareControl(name.c_str(),
  968. typeStringToEnum(control_map["Type"].asString()),
  969. control_map["Value"],
  970. control_map["Comment"].asString(),
  971. persist, hide_from_editor);
  972. }
  973. ++validitems;
  974. }
  975. return validitems;
  976. }
  977. void LLControlGroup::resetToDefaults()
  978. {
  979. for (ctrl_name_table_t::iterator it = mNameTable.begin(),
  980. end = mNameTable.end();
  981. it != end; ++it)
  982. {
  983. (it->second)->resetToDefault();
  984. }
  985. }
  986. void LLControlGroup::applyToAll(ApplyFunctor* func)
  987. {
  988. for (ctrl_name_table_t::iterator iter = mNameTable.begin();
  989. iter != mNameTable.end(); iter++)
  990. {
  991. func->apply(iter->first, iter->second);
  992. }
  993. }
  994. template<> eControlType get_control_type<U32>()
  995. {
  996. return TYPE_U32;
  997. }
  998. template<> eControlType get_control_type<S32>()
  999. {
  1000. return TYPE_S32;
  1001. }
  1002. template<> eControlType get_control_type<F32>()
  1003. {
  1004. return TYPE_F32;
  1005. }
  1006. template<> eControlType get_control_type<bool>()
  1007. {
  1008. return TYPE_BOOLEAN;
  1009. }
  1010. template<> eControlType get_control_type<std::string>()
  1011. {
  1012. return TYPE_STRING;
  1013. }
  1014. template<> eControlType get_control_type<LLVector3>()
  1015. {
  1016. return TYPE_VEC3;
  1017. }
  1018. template<> eControlType get_control_type<LLVector3d>()
  1019. {
  1020. return TYPE_VEC3D;
  1021. }
  1022. template<> eControlType get_control_type<LLRect>()
  1023. {
  1024. return TYPE_RECT;
  1025. }
  1026. template<> eControlType get_control_type<LLColor4>()
  1027. {
  1028. return TYPE_COL4;
  1029. }
  1030. template<> eControlType get_control_type<LLColor4U>()
  1031. {
  1032. return TYPE_COL4U;
  1033. }
  1034. template<> eControlType get_control_type<LLColor3>()
  1035. {
  1036. return TYPE_COL3;
  1037. }
  1038. template<> eControlType get_control_type<LLSD>()
  1039. {
  1040. return TYPE_LLSD;
  1041. }
  1042. template<> LLSD convert_to_llsd<U32>(const U32& in)
  1043. {
  1044. return (LLSD::Integer)in;
  1045. }
  1046. template<> LLSD convert_to_llsd<LLVector3>(const LLVector3& in)
  1047. {
  1048. return in.getValue();
  1049. }
  1050. template<> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in)
  1051. {
  1052. return in.getValue();
  1053. }
  1054. template<> LLSD convert_to_llsd<LLRect>(const LLRect& in)
  1055. {
  1056. return in.getValue();
  1057. }
  1058. template<> LLSD convert_to_llsd<LLColor4>(const LLColor4& in)
  1059. {
  1060. return in.getValue();
  1061. }
  1062. template<> LLSD convert_to_llsd<LLColor4U>(const LLColor4U& in)
  1063. {
  1064. return in.getValue();
  1065. }
  1066. template<> LLSD convert_to_llsd<LLColor3>(const LLColor3& in)
  1067. {
  1068. return in.getValue();
  1069. }
  1070. template<> bool convert_from_llsd<bool>(const LLSD& sd, eControlType type,
  1071. const char* control_name)
  1072. {
  1073. if (type == TYPE_BOOLEAN)
  1074. {
  1075. return sd.asBoolean();
  1076. }
  1077. CONTROL_ERRS << "Invalid bool value for " << control_name << ": " << sd
  1078. << llendl;
  1079. if (type == TYPE_S32 || type == TYPE_U32)
  1080. {
  1081. return sd.asInteger() != 0;
  1082. }
  1083. return false;
  1084. }
  1085. template<> S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type,
  1086. const char* control_name)
  1087. {
  1088. // *HACK: TYPE_U32 needed for LLCachedControl<U32> !
  1089. if (type == TYPE_S32 || type == TYPE_U32)
  1090. {
  1091. return sd.asInteger();
  1092. }
  1093. CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << sd
  1094. << llendl;
  1095. return 0;
  1096. }
  1097. template<> U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type,
  1098. const char* control_name)
  1099. {
  1100. if (type == TYPE_U32)
  1101. {
  1102. return sd.asInteger();
  1103. }
  1104. CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << sd
  1105. << llendl;
  1106. if (type == TYPE_S32 && sd.asInteger() >= 0)
  1107. {
  1108. return sd.asInteger();
  1109. }
  1110. return 0;
  1111. }
  1112. template<> F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type,
  1113. const char* control_name)
  1114. {
  1115. if (type == TYPE_F32)
  1116. {
  1117. return (F32)sd.asReal();
  1118. }
  1119. CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << sd
  1120. << llendl;
  1121. if (type == TYPE_S32 || type == TYPE_U32)
  1122. {
  1123. return (F32)sd.asInteger();
  1124. }
  1125. return 0.0f;
  1126. }
  1127. template<> std::string convert_from_llsd<std::string>(const LLSD& sd,
  1128. eControlType type,
  1129. const char* control_name)
  1130. {
  1131. if (type == TYPE_STRING)
  1132. {
  1133. return sd.asString();
  1134. }
  1135. CONTROL_ERRS << "Invalid string value for " << control_name << ": "
  1136. << sd << llendl;
  1137. return LLStringUtil::null;
  1138. }
  1139. template<> LLWString convert_from_llsd<LLWString>(const LLSD& sd,
  1140. eControlType type,
  1141. const char* control_name)
  1142. {
  1143. return utf8str_to_wstring(convert_from_llsd<std::string>(sd, type, control_name));
  1144. }
  1145. template<> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd,
  1146. eControlType type,
  1147. const char* control_name)
  1148. {
  1149. if (type == TYPE_VEC3)
  1150. {
  1151. return (LLVector3)sd;
  1152. }
  1153. CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": "
  1154. << sd << llendl;
  1155. return LLVector3::zero;
  1156. }
  1157. template<> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd,
  1158. eControlType type,
  1159. const char* control_name)
  1160. {
  1161. if (type == TYPE_VEC3D)
  1162. {
  1163. return (LLVector3d)sd;
  1164. }
  1165. CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": "
  1166. << sd << llendl;
  1167. return LLVector3d::zero;
  1168. }
  1169. template<> LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type,
  1170. const char* control_name)
  1171. {
  1172. if (type == TYPE_RECT)
  1173. {
  1174. return LLRect(sd);
  1175. }
  1176. CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << sd
  1177. << llendl;
  1178. return LLRect::null;
  1179. }
  1180. template<> LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd,
  1181. eControlType type,
  1182. const char* control_name)
  1183. {
  1184. if (type == TYPE_COL4)
  1185. {
  1186. LLColor4 color(sd);
  1187. if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f)
  1188. {
  1189. llwarns << "Color " << control_name
  1190. << " red value out of range: " << color << llendl;
  1191. }
  1192. if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f)
  1193. {
  1194. llwarns << "Color " << control_name
  1195. << " green value out of range: " << color << llendl;
  1196. }
  1197. if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f)
  1198. {
  1199. llwarns << "Color " << control_name
  1200. << " blue value out of range: " << color << llendl;
  1201. }
  1202. if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f)
  1203. {
  1204. llwarns << "Color " << control_name
  1205. << " alpha value out of range: " << color << llendl;
  1206. }
  1207. return LLColor4(sd);
  1208. }
  1209. CONTROL_ERRS << "Control " << control_name << " not a color" << llendl;
  1210. return LLColor4::white;
  1211. }
  1212. template<> LLColor4U convert_from_llsd<LLColor4U>(const LLSD& sd,
  1213. eControlType type,
  1214. const char* control_name)
  1215. {
  1216. if (type == TYPE_COL4U)
  1217. {
  1218. return LLColor4U(sd);
  1219. }
  1220. CONTROL_ERRS << "Invalid LLColor4U value for " << control_name << ": "
  1221. << sd << llendl;
  1222. return LLColor4U::white;
  1223. }
  1224. template<> LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd,
  1225. eControlType type,
  1226. const char* control_name)
  1227. {
  1228. if (type == TYPE_COL3)
  1229. {
  1230. return sd;
  1231. }
  1232. CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": "
  1233. << sd << llendl;
  1234. return LLColor3::white;
  1235. }
  1236. template<> LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type,
  1237. const char* control_name)
  1238. {
  1239. return sd;
  1240. }
  1241. //============================================================================
  1242. // First-use
  1243. static std::string get_warn_name(const std::string& name)
  1244. {
  1245. std::string warnname = "Warn" + name;
  1246. for (std::string::iterator iter = warnname.begin(); iter != warnname.end();
  1247. ++iter)
  1248. {
  1249. char c = *iter;
  1250. if (!isalnum(c))
  1251. {
  1252. *iter = '_';
  1253. }
  1254. }
  1255. return warnname;
  1256. }
  1257. // Note: may get called more than once per warning (e.g. if already loaded from
  1258. // a settings file), but that is OK, declareBool will handle it.
  1259. void LLControlGroup::addWarning(const std::string& name)
  1260. {
  1261. std::string warnname = get_warn_name(name);
  1262. std::string comment = "Enables " + name + " warning dialog";
  1263. declareBool(warnname.c_str(), true, comment);
  1264. mWarnings.emplace(warnname);
  1265. }
  1266. bool LLControlGroup::getWarning(const std::string& name)
  1267. {
  1268. std::string warnname = get_warn_name(name);
  1269. return getBool(warnname.c_str());
  1270. }
  1271. void LLControlGroup::setWarning(const std::string& name, bool val)
  1272. {
  1273. std::string warnname = get_warn_name(name);
  1274. setBool(warnname.c_str(), val);
  1275. }
  1276. void LLControlGroup::resetWarnings()
  1277. {
  1278. for (std::set<std::string>::iterator iter = mWarnings.begin();
  1279. iter != mWarnings.end(); ++iter)
  1280. {
  1281. setBool(iter->c_str(), true);
  1282. }
  1283. }