00001
00032 #include "linden_common.h"
00033
00034 #include <iostream>
00035 #include <fstream>
00036 #include <algorithm>
00037
00038 #include "llcontrol.h"
00039
00040 #include "llstl.h"
00041
00042 #include "llstring.h"
00043 #include "v3math.h"
00044 #include "v3dmath.h"
00045 #include "v4coloru.h"
00046 #include "v4color.h"
00047 #include "v3color.h"
00048 #include "llrect.h"
00049 #include "llxmltree.h"
00050 #include "llsdserialize.h"
00051
00052 #if LL_RELEASE_FOR_DOWNLOAD
00053 #define CONTROL_ERRS LL_WARNS("ControlErrors")
00054 #else
00055 #define CONTROL_ERRS LL_ERRS("ControlErrors")
00056 #endif
00057
00058
00059 const S32 CURRENT_VERSION = 101;
00060
00061 BOOL LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
00062 {
00063 switch (mType)
00064 {
00065 case TYPE_U32:
00066 case TYPE_S32:
00067 return a.asInteger() == b.asInteger();
00068 case TYPE_BOOLEAN:
00069 return a.asBoolean() == b.asBoolean();
00070 case TYPE_F32:
00071 return a.asReal() == b.asReal();
00072 case TYPE_VEC3:
00073 case TYPE_VEC3D:
00074 return LLVector3d(a) == LLVector3d(b);
00075 case TYPE_RECT:
00076 return LLRect(a) == LLRect(b);
00077 case TYPE_COL4:
00078 return LLColor4(a) == LLColor4(b);
00079 case TYPE_COL3:
00080 return LLColor3(a) == LLColor3(b);
00081 case TYPE_COL4U:
00082 return LLColor4U(a) == LLColor4U(b);
00083 case TYPE_STRING:
00084 return a.asString() == b.asString();
00085 default:
00086
00087 break;
00088 }
00089
00090 return FALSE;
00091 }
00092
00093 LLControlVariable::LLControlVariable(const LLString& name, eControlType type,
00094 LLSD initial, const LLString& comment,
00095 BOOL persist)
00096 : mName(name),
00097 mComment(comment),
00098 mType(type),
00099 mPersist(persist)
00100 {
00101 if (mPersist && mComment.empty())
00102 {
00103 llerrs << "Must supply a comment for control " << mName << llendl;
00104 }
00105
00106 mValues.push_back(initial);
00107 }
00108
00109
00110
00111 LLControlVariable::~LLControlVariable()
00112 {
00113 }
00114
00115 void LLControlVariable::setValue(const LLSD& value, bool saved_value)
00116 {
00117 bool value_changed = llsd_compare(getValue(), value) == FALSE;
00118 if(saved_value)
00119 {
00120
00121 resetToDefault(false);
00122 if (llsd_compare(mValues.back(), value) == FALSE)
00123 {
00124 mValues.push_back(value);
00125 }
00126 }
00127 else
00128 {
00129
00130
00131
00132 if (llsd_compare(mValues.back(), value) == FALSE)
00133 {
00134 while(mValues.size() > 2)
00135 {
00136
00137 mValues.pop_back();
00138 }
00139
00140 if(mValues.size() < 2)
00141 {
00142
00143 mValues.push_back(mValues[0]);
00144 }
00145
00146
00147 mValues.push_back(value);
00148 }
00149 }
00150
00151 if(value_changed)
00152 {
00153 mSignal(value);
00154 }
00155 }
00156
00157 void LLControlVariable::resetToDefault(bool fire_signal)
00158 {
00159
00160
00161 while(mValues.size() > 1) mValues.pop_back();
00162 if(fire_signal) firePropertyChanged();
00163 }
00164
00165 bool LLControlVariable::isSaveValueDefault()
00166 {
00167 return (mValues.size() == 1)
00168 || ((mValues.size() > 1) && llsd_compare(mValues[1], mValues[0]));
00169 }
00170
00171 LLSD LLControlVariable::getSaveValue() const
00172 {
00173
00174
00175 if(mValues.size() > 1) return mValues[1];
00176 return mValues[0];
00177 }
00178
00179 LLControlVariable* LLControlGroup::getControl(const LLString& name)
00180 {
00181 ctrl_name_table_t::iterator iter = mNameTable.find(name);
00182 return iter == mNameTable.end() ? NULL : iter->second;
00183 }
00184
00185
00187
00188 LLControlGroup::LLControlGroup()
00189 {
00190 mTypeString[TYPE_U32] = "U32";
00191 mTypeString[TYPE_S32] = "S32";
00192 mTypeString[TYPE_F32] = "F32";
00193 mTypeString[TYPE_BOOLEAN] = "Boolean";
00194 mTypeString[TYPE_STRING] = "String";
00195 mTypeString[TYPE_VEC3] = "Vector3";
00196 mTypeString[TYPE_VEC3D] = "Vector3D";
00197 mTypeString[TYPE_RECT] = "Rect";
00198 mTypeString[TYPE_COL4] = "Color4";
00199 mTypeString[TYPE_COL3] = "Color3";
00200 mTypeString[TYPE_COL4U] = "Color4u";
00201 mTypeString[TYPE_LLSD] = "LLSD";
00202 }
00203
00204 LLControlGroup::~LLControlGroup()
00205 {
00206 cleanup();
00207 }
00208
00209 void LLControlGroup::cleanup()
00210 {
00211 for_each(mNameTable.begin(), mNameTable.end(), DeletePairedPointer());
00212 mNameTable.clear();
00213 }
00214
00215 eControlType LLControlGroup::typeStringToEnum(const LLString& typestr)
00216 {
00217 for(int i = 0; i < (int)TYPE_COUNT; ++i)
00218 {
00219 if(mTypeString[i] == typestr) return (eControlType)i;
00220 }
00221 return (eControlType)-1;
00222 }
00223
00224 LLString LLControlGroup::typeEnumToString(eControlType typeenum)
00225 {
00226 return mTypeString[typeenum];
00227 }
00228
00229 BOOL LLControlGroup::declareControl(const LLString& name, eControlType type, const LLSD initial_val, const LLString& comment, BOOL persist)
00230 {
00231 if(mNameTable.find(name) != mNameTable.end())
00232 {
00233 llwarns << "LLControlGroup::declareControl: Control named " << name << " already exists." << llendl;
00234 mNameTable[name]->setValue(initial_val);
00235 return TRUE;
00236 }
00237
00238 LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist);
00239 mNameTable[name] = control;
00240 return TRUE;
00241 }
00242
00243 BOOL LLControlGroup::declareU32(const LLString& name, const U32 initial_val, const LLString& comment, BOOL persist)
00244 {
00245 return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist);
00246 }
00247
00248 BOOL LLControlGroup::declareS32(const LLString& name, const S32 initial_val, const LLString& comment, BOOL persist)
00249 {
00250 return declareControl(name, TYPE_S32, initial_val, comment, persist);
00251 }
00252
00253 BOOL LLControlGroup::declareF32(const LLString& name, const F32 initial_val, const LLString& comment, BOOL persist)
00254 {
00255 return declareControl(name, TYPE_F32, initial_val, comment, persist);
00256 }
00257
00258 BOOL LLControlGroup::declareBOOL(const LLString& name, const BOOL initial_val, const LLString& comment, BOOL persist)
00259 {
00260 return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist);
00261 }
00262
00263 BOOL LLControlGroup::declareString(const LLString& name, const LLString& initial_val, const LLString& comment, BOOL persist)
00264 {
00265 return declareControl(name, TYPE_STRING, initial_val, comment, persist);
00266 }
00267
00268 BOOL LLControlGroup::declareVec3(const LLString& name, const LLVector3 &initial_val, const LLString& comment, BOOL persist)
00269 {
00270 return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist);
00271 }
00272
00273 BOOL LLControlGroup::declareVec3d(const LLString& name, const LLVector3d &initial_val, const LLString& comment, BOOL persist)
00274 {
00275 return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist);
00276 }
00277
00278 BOOL LLControlGroup::declareRect(const LLString& name, const LLRect &initial_val, const LLString& comment, BOOL persist)
00279 {
00280 return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist);
00281 }
00282
00283 BOOL LLControlGroup::declareColor4U(const LLString& name, const LLColor4U &initial_val, const LLString& comment, BOOL persist )
00284 {
00285 return declareControl(name, TYPE_COL4U, initial_val.getValue(), comment, persist);
00286 }
00287
00288 BOOL LLControlGroup::declareColor4(const LLString& name, const LLColor4 &initial_val, const LLString& comment, BOOL persist )
00289 {
00290 return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist);
00291 }
00292
00293 BOOL LLControlGroup::declareColor3(const LLString& name, const LLColor3 &initial_val, const LLString& comment, BOOL persist )
00294 {
00295 return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist);
00296 }
00297
00298 BOOL LLControlGroup::declareLLSD(const LLString& name, const LLSD &initial_val, const LLString& comment, BOOL persist )
00299 {
00300 return declareControl(name, TYPE_LLSD, initial_val, comment, persist);
00301 }
00302
00303 BOOL LLControlGroup::getBOOL(const LLString& name)
00304 {
00305 LLControlVariable* control = getControl(name);
00306
00307 if (control && control->isType(TYPE_BOOLEAN))
00308 return control->get().asBoolean();
00309 else
00310 {
00311 CONTROL_ERRS << "Invalid BOOL control " << name << llendl;
00312 return FALSE;
00313 }
00314 }
00315
00316 S32 LLControlGroup::getS32(const LLString& name)
00317 {
00318 LLControlVariable* control = getControl(name);
00319
00320 if (control && control->isType(TYPE_S32))
00321 return control->get().asInteger();
00322 else
00323 {
00324 CONTROL_ERRS << "Invalid S32 control " << name << llendl;
00325 return 0;
00326 }
00327 }
00328
00329 U32 LLControlGroup::getU32(const LLString& name)
00330 {
00331 LLControlVariable* control = getControl(name);
00332
00333 if (control && control->isType(TYPE_U32))
00334 return control->get().asInteger();
00335 else
00336 {
00337 CONTROL_ERRS << "Invalid U32 control " << name << llendl;
00338 return 0;
00339 }
00340 }
00341
00342 F32 LLControlGroup::getF32(const LLString& name)
00343 {
00344 LLControlVariable* control = getControl(name);
00345
00346 if (control && control->isType(TYPE_F32))
00347 return (F32) control->get().asReal();
00348 else
00349 {
00350 CONTROL_ERRS << "Invalid F32 control " << name << llendl;
00351 return 0.0f;
00352 }
00353 }
00354
00355 LLString LLControlGroup::findString(const LLString& name)
00356 {
00357 LLControlVariable* control = getControl(name);
00358
00359 if (control && control->isType(TYPE_STRING))
00360 return control->get().asString();
00361 return LLString::null;
00362 }
00363
00364 LLString LLControlGroup::getString(const LLString& name)
00365 {
00366 LLControlVariable* control = getControl(name);
00367
00368 if (control && control->isType(TYPE_STRING))
00369 return control->get().asString();
00370 else
00371 {
00372 CONTROL_ERRS << "Invalid string control " << name << llendl;
00373 return LLString::null;
00374 }
00375 }
00376
00377 LLWString LLControlGroup::getWString(const LLString& name)
00378 {
00379 return utf8str_to_wstring(getString(name));
00380 }
00381
00382 LLString LLControlGroup::getText(const LLString& name)
00383 {
00384 LLString utf8_string = getString(name);
00385 LLString::replaceChar(utf8_string, '^', '\n');
00386 LLString::replaceChar(utf8_string, '%', ' ');
00387 return (utf8_string);
00388 }
00389
00390 LLVector3 LLControlGroup::getVector3(const LLString& name)
00391 {
00392 LLControlVariable* control = getControl(name);
00393
00394 if (control && control->isType(TYPE_VEC3))
00395 return control->get();
00396 else
00397 {
00398 CONTROL_ERRS << "Invalid LLVector3 control " << name << llendl;
00399 return LLVector3::zero;
00400 }
00401 }
00402
00403 LLVector3d LLControlGroup::getVector3d(const LLString& name)
00404 {
00405 LLControlVariable* control = getControl(name);
00406
00407 if (control && control->isType(TYPE_VEC3D))
00408 return control->get();
00409 else
00410 {
00411 CONTROL_ERRS << "Invalid LLVector3d control " << name << llendl;
00412 return LLVector3d::zero;
00413 }
00414 }
00415
00416 LLRect LLControlGroup::getRect(const LLString& name)
00417 {
00418 LLControlVariable* control = getControl(name);
00419
00420 if (control && control->isType(TYPE_RECT))
00421 return control->get();
00422 else
00423 {
00424 CONTROL_ERRS << "Invalid rect control " << name << llendl;
00425 return LLRect::null;
00426 }
00427 }
00428
00429
00430 LLColor4 LLControlGroup::getColor(const LLString& name)
00431 {
00432 ctrl_name_table_t::const_iterator i = mNameTable.find(name);
00433
00434 if (i != mNameTable.end())
00435 {
00436 LLControlVariable* control = i->second;
00437
00438 switch(control->mType)
00439 {
00440 case TYPE_COL4:
00441 {
00442 return LLColor4(control->get());
00443 }
00444 case TYPE_COL4U:
00445 {
00446 return LLColor4(LLColor4U(control->get()));
00447 }
00448 default:
00449 {
00450 CONTROL_ERRS << "Control " << name << " not a color" << llendl;
00451 return LLColor4::white;
00452 }
00453 }
00454 }
00455 else
00456 {
00457 CONTROL_ERRS << "Invalid getColor control " << name << llendl;
00458 return LLColor4::white;
00459 }
00460 }
00461
00462 LLColor4U LLControlGroup::getColor4U(const LLString& name)
00463 {
00464 LLControlVariable* control = getControl(name);
00465
00466 if (control && control->isType(TYPE_COL4U))
00467 return control->get();
00468 else
00469 {
00470 CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl;
00471 return LLColor4U::white;
00472 }
00473 }
00474
00475 LLColor4 LLControlGroup::getColor4(const LLString& name)
00476 {
00477 LLControlVariable* control = getControl(name);
00478
00479 if (control && control->isType(TYPE_COL4))
00480 return control->get();
00481 else
00482 {
00483 CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl;
00484 return LLColor4::white;
00485 }
00486 }
00487
00488 LLColor3 LLControlGroup::getColor3(const LLString& name)
00489 {
00490 LLControlVariable* control = getControl(name);
00491
00492 if (control && control->isType(TYPE_COL3))
00493 return control->get();
00494 else
00495 {
00496 CONTROL_ERRS << "Invalid LLColor3 control " << name << llendl;
00497 return LLColor3::white;
00498 }
00499 }
00500
00501 LLSD LLControlGroup::getLLSD(const LLString& name)
00502 {
00503 LLControlVariable* control = getControl(name);
00504
00505 if (control && control->isType(TYPE_LLSD))
00506 return control->getValue();
00507 CONTROL_ERRS << "Invalid LLSD control " << name << llendl;
00508 return LLSD();
00509 }
00510
00511 BOOL LLControlGroup::controlExists(const LLString& name)
00512 {
00513 ctrl_name_table_t::iterator iter = mNameTable.find(name);
00514 return iter != mNameTable.end();
00515 }
00516
00517
00518
00519
00520
00521 void LLControlGroup::setBOOL(const LLString& name, BOOL val)
00522 {
00523 LLControlVariable* control = getControl(name);
00524
00525 if (control && control->isType(TYPE_BOOLEAN))
00526 {
00527 control->set(val);
00528 }
00529 else
00530 {
00531 CONTROL_ERRS << "Invalid control " << name << llendl;
00532 }
00533 }
00534
00535
00536 void LLControlGroup::setS32(const LLString& name, S32 val)
00537 {
00538 LLControlVariable* control = getControl(name);
00539
00540 if (control && control->isType(TYPE_S32))
00541 {
00542 control->set(val);
00543 }
00544 else
00545 {
00546 CONTROL_ERRS << "Invalid control " << name << llendl;
00547 }
00548 }
00549
00550
00551 void LLControlGroup::setF32(const LLString& name, F32 val)
00552 {
00553 LLControlVariable* control = getControl(name);
00554
00555 if (control && control->isType(TYPE_F32))
00556 {
00557 control->set(val);
00558 }
00559 else
00560 {
00561 CONTROL_ERRS << "Invalid control " << name << llendl;
00562 }
00563 }
00564
00565
00566 void LLControlGroup::setU32(const LLString& name, U32 val)
00567 {
00568 LLControlVariable* control = getControl(name);
00569
00570 if (control && control->isType(TYPE_U32))
00571 {
00572 control->set((LLSD::Integer) val);
00573 }
00574 else
00575 {
00576 CONTROL_ERRS << "Invalid control " << name << llendl;
00577 }
00578 }
00579
00580
00581 void LLControlGroup::setString(const LLString& name, const LLString &val)
00582 {
00583 LLControlVariable* control = getControl(name);
00584
00585 if (control && control->isType(TYPE_STRING))
00586 {
00587 control->set(val);
00588 }
00589 else
00590 {
00591 CONTROL_ERRS << "Invalid control " << name << llendl;
00592 }
00593 }
00594
00595
00596 void LLControlGroup::setVector3(const LLString& name, const LLVector3 &val)
00597 {
00598 LLControlVariable* control = getControl(name);
00599
00600 if (control && control->isType(TYPE_VEC3))
00601 {
00602 control->set(val.getValue());
00603 }
00604 else
00605 {
00606 CONTROL_ERRS << "Invalid control " << name << llendl;
00607 }
00608 }
00609
00610 void LLControlGroup::setVector3d(const LLString& name, const LLVector3d &val)
00611 {
00612 LLControlVariable* control = getControl(name);
00613
00614 if (control && control->isType(TYPE_VEC3D))
00615 {
00616 control->set(val.getValue());
00617 }
00618 else
00619 {
00620 CONTROL_ERRS << "Invalid control " << name << llendl;
00621 }
00622 }
00623
00624 void LLControlGroup::setRect(const LLString& name, const LLRect &val)
00625 {
00626 LLControlVariable* control = getControl(name);
00627
00628 if (control && control->isType(TYPE_RECT))
00629 {
00630 control->set(val.getValue());
00631 }
00632 else
00633 {
00634 CONTROL_ERRS << "Invalid rect control " << name << llendl;
00635 }
00636 }
00637
00638 void LLControlGroup::setColor4U(const LLString& name, const LLColor4U &val)
00639 {
00640 LLControlVariable* control = getControl(name);
00641
00642 if (control && control->isType(TYPE_COL4U))
00643 {
00644 control->set(val.getValue());
00645 }
00646 else
00647 {
00648 CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl;
00649 }
00650 }
00651
00652 void LLControlGroup::setColor4(const LLString& name, const LLColor4 &val)
00653 {
00654 LLControlVariable* control = getControl(name);
00655
00656 if (control && control->isType(TYPE_COL4))
00657 {
00658 control->set(val.getValue());
00659 }
00660 else
00661 {
00662 CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl;
00663 }
00664 }
00665
00666 void LLControlGroup::setLLSD(const LLString& name, const LLSD& val)
00667 {
00668 LLControlVariable* control = getControl(name);
00669
00670 if (control && control->isType(TYPE_LLSD))
00671 {
00672 setValue(name, val);
00673 }
00674 else
00675 {
00676 CONTROL_ERRS << "Invalid LLSD control " << name << llendl;
00677 }
00678 }
00679
00680 void LLControlGroup::setValue(const LLString& name, const LLSD& val)
00681 {
00682 if (name.empty())
00683 {
00684 return;
00685 }
00686
00687 LLControlVariable* control = getControl(name);
00688
00689 if (control)
00690 {
00691 control->set(val);
00692 }
00693 else
00694 {
00695 CONTROL_ERRS << "Invalid control " << name << llendl;
00696 }
00697 }
00698
00699
00700
00701
00702
00703
00704 U32 LLControlGroup::loadFromFileLegacy(const LLString& filename, BOOL require_declaration, eControlType declare_as)
00705 {
00706 LLString name;
00707
00708 LLXmlTree xml_controls;
00709
00710 if (!xml_controls.parseFile(filename))
00711 {
00712 llwarns << "Unable to open control file " << filename << llendl;
00713 return 0;
00714 }
00715
00716 LLXmlTreeNode* rootp = xml_controls.getRoot();
00717 if (!rootp || !rootp->hasAttribute("version"))
00718 {
00719 llwarns << "No valid settings header found in control file " << filename << llendl;
00720 return 0;
00721 }
00722
00723 U32 item = 0;
00724 U32 validitems = 0;
00725 S32 version;
00726
00727 rootp->getAttributeS32("version", version);
00728
00729
00730 if (version != CURRENT_VERSION)
00731 {
00732 llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl;
00733 return 0;
00734 }
00735
00736 LLXmlTreeNode* child_nodep = rootp->getFirstChild();
00737 while(child_nodep)
00738 {
00739 name = child_nodep->getName();
00740
00741 BOOL declared = controlExists(name);
00742
00743 if (require_declaration && !declared)
00744 {
00745
00746
00747 if (!name.empty())
00748 {
00749
00750 llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
00751 }
00752 child_nodep = rootp->getNextChild();
00753 continue;
00754 }
00755
00756
00757 item++;
00758
00759
00760 if (!declared)
00761 {
00762 switch(declare_as)
00763 {
00764 case TYPE_COL4:
00765 declareColor4(name, LLColor4::white, "", NO_PERSIST);
00766 break;
00767 case TYPE_COL4U:
00768 declareColor4U(name, LLColor4U::white, "", NO_PERSIST);
00769 break;
00770 case TYPE_STRING:
00771 default:
00772 declareString(name, LLString::null, "", NO_PERSIST);
00773 break;
00774 }
00775 }
00776
00777
00778 LLControlVariable *control = getControl(name);
00779
00780 llassert(control);
00781
00782 switch(control->mType)
00783 {
00784 case TYPE_F32:
00785 {
00786 F32 initial = 0.f;
00787
00788 child_nodep->getAttributeF32("value", initial);
00789
00790 control->set(initial);
00791 validitems++;
00792 }
00793 break;
00794 case TYPE_S32:
00795 {
00796 S32 initial = 0;
00797
00798 child_nodep->getAttributeS32("value", initial);
00799
00800 control->set(initial);
00801 validitems++;
00802 }
00803 break;
00804 case TYPE_U32:
00805 {
00806 U32 initial = 0;
00807 child_nodep->getAttributeU32("value", initial);
00808 control->set((LLSD::Integer) initial);
00809 validitems++;
00810 }
00811 break;
00812 case TYPE_BOOLEAN:
00813 {
00814 BOOL initial = FALSE;
00815
00816 child_nodep->getAttributeBOOL("value", initial);
00817 control->set(initial);
00818
00819 validitems++;
00820 }
00821 break;
00822 case TYPE_STRING:
00823 {
00824 LLString string;
00825 child_nodep->getAttributeString("value", string);
00826 if (string == LLString::null)
00827 {
00828 string = "";
00829 }
00830 control->set(string);
00831 validitems++;
00832 }
00833 break;
00834 case TYPE_VEC3:
00835 {
00836 LLVector3 vector;
00837
00838 child_nodep->getAttributeVector3("value", vector);
00839 control->set(vector.getValue());
00840 validitems++;
00841 }
00842 break;
00843 case TYPE_VEC3D:
00844 {
00845 LLVector3d vector;
00846
00847 child_nodep->getAttributeVector3d("value", vector);
00848
00849 control->set(vector.getValue());
00850 validitems++;
00851 }
00852 break;
00853 case TYPE_RECT:
00854 {
00855
00856 LLString rect_string;
00857
00858 child_nodep->getAttributeString("value", rect_string);
00859 std::istringstream istream(rect_string);
00860 S32 left, bottom, width, height;
00861
00862 istream >> left >> bottom >> width >> height;
00863
00864 LLRect rect;
00865 rect.setOriginAndSize(left, bottom, width, height);
00866
00867 control->set(rect.getValue());
00868 validitems++;
00869 }
00870 break;
00871 case TYPE_COL4U:
00872 {
00873 LLColor4U color;
00874
00875 child_nodep->getAttributeColor4U("value", color);
00876 control->set(color.getValue());
00877 validitems++;
00878 }
00879 break;
00880 case TYPE_COL4:
00881 {
00882 LLColor4 color;
00883
00884 child_nodep->getAttributeColor4("value", color);
00885 control->set(color.getValue());
00886 validitems++;
00887 }
00888 break;
00889 case TYPE_COL3:
00890 {
00891 LLVector3 color;
00892
00893 child_nodep->getAttributeVector3("value", color);
00894 control->set(LLColor3(color.mV).getValue());
00895 validitems++;
00896 }
00897 break;
00898
00899 default:
00900 break;
00901
00902 }
00903
00904 child_nodep = rootp->getNextChild();
00905 }
00906
00907 return validitems;
00908 }
00909
00910 U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only)
00911 {
00912 LLSD settings;
00913 int num_saved = 0;
00914 for (ctrl_name_table_t::iterator iter = mNameTable.begin();
00915 iter != mNameTable.end(); iter++)
00916 {
00917 LLControlVariable* control = iter->second;
00918 if (!control)
00919 {
00920 llwarns << "Tried to save invalid control: " << iter->first << llendl;
00921 }
00922
00923 if( control && control->isPersisted() )
00924 {
00925 if (!(nondefault_only && (control->isSaveValueDefault())))
00926 {
00927 settings[iter->first]["Type"] = typeEnumToString(control->type());
00928 settings[iter->first]["Comment"] = control->getComment();
00929 settings[iter->first]["Value"] = control->getSaveValue();
00930 ++num_saved;
00931 }
00932 else
00933 {
00934
00935
00936 }
00937 }
00938 }
00939 llofstream file;
00940 file.open(filename.c_str());
00941 if (file.is_open())
00942 {
00943 LLSDSerialize::toPrettyXML(settings, file);
00944 file.close();
00945 llinfos << "Saved to " << filename << llendl;
00946 }
00947 else
00948 {
00949
00950 llwarns << "Unable to open settings file: " << filename << llendl;
00951 return 0;
00952 }
00953 return num_saved;
00954 }
00955
00956 U32 LLControlGroup::loadFromFile(const LLString& filename)
00957 {
00958 LLString name;
00959 LLSD settings;
00960 LLSD control_map;
00961 llifstream infile;
00962 infile.open(filename.c_str());
00963 if(!infile.is_open())
00964 {
00965 llwarns << "Cannot find file " << filename << " to load." << llendl;
00966 return 0;
00967 }
00968
00969 S32 ret = LLSDSerialize::fromXML(settings, infile);
00970
00971 if (ret <= 0)
00972 {
00973 infile.close();
00974 llwarns << "Unable to open LLSD control file " << filename << ". Trying Legacy Method." << llendl;
00975 return loadFromFileLegacy(filename, TRUE, TYPE_STRING);
00976 }
00977
00978 U32 validitems = 0;
00979 int persist = 1;
00980 for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr)
00981 {
00982 name = (*itr).first;
00983 control_map = (*itr).second;
00984
00985 if(control_map.has("Persist"))
00986 {
00987 persist = control_map["Persist"].asInteger();
00988 }
00989
00990
00991 LLControlVariable* existing_control = getControl(name);
00992 if(existing_control)
00993 {
00994
00995 if(existing_control->isPersisted())
00996 {
00997 existing_control->setValue(control_map["Value"]);
00998 }
00999 }
01000 else
01001 {
01002 declareControl(name,
01003 typeStringToEnum(control_map["Type"].asString()),
01004 control_map["Value"],
01005 control_map["Comment"].asString(),
01006 persist
01007 );
01008 }
01009
01010 ++validitems;
01011 }
01012
01013 return validitems;
01014 }
01015
01016 void LLControlGroup::resetToDefaults()
01017 {
01018 ctrl_name_table_t::iterator control_iter;
01019 for (control_iter = mNameTable.begin();
01020 control_iter != mNameTable.end();
01021 ++control_iter)
01022 {
01023 LLControlVariable* control = (*control_iter).second;
01024 control->resetToDefault();
01025 }
01026 }
01027
01028 void LLControlGroup::applyToAll(ApplyFunctor* func)
01029 {
01030 for (ctrl_name_table_t::iterator iter = mNameTable.begin();
01031 iter != mNameTable.end(); iter++)
01032 {
01033 func->apply(iter->first, iter->second);
01034 }
01035 }
01036
01037
01038
01039
01040 static LLString get_warn_name(const LLString& name)
01041 {
01042 LLString warnname = "Warn" + name;
01043 for (LLString::iterator iter = warnname.begin(); iter != warnname.end(); ++iter)
01044 {
01045 char c = *iter;
01046 if (!isalnum(c))
01047 {
01048 *iter = '_';
01049 }
01050 }
01051 return warnname;
01052 }
01053
01054 void LLControlGroup::addWarning(const LLString& name)
01055 {
01056 LLString warnname = get_warn_name(name);
01057 if(mNameTable.find(warnname) == mNameTable.end())
01058 {
01059 LLString comment = LLString("Enables ") + name + LLString(" warning dialog");
01060 declareBOOL(warnname, TRUE, comment);
01061 mWarnings.insert(warnname);
01062 }
01063 }
01064
01065 BOOL LLControlGroup::getWarning(const LLString& name)
01066 {
01067 LLString warnname = get_warn_name(name);
01068 return getBOOL(warnname);
01069 }
01070
01071 void LLControlGroup::setWarning(const LLString& name, BOOL val)
01072 {
01073 LLString warnname = get_warn_name(name);
01074 setBOOL(warnname, val);
01075 }
01076
01077 void LLControlGroup::resetWarnings()
01078 {
01079 for (std::set<LLString>::iterator iter = mWarnings.begin();
01080 iter != mWarnings.end(); ++iter)
01081 {
01082 setBOOL(*iter, TRUE);
01083 }
01084 }
01085
01086
01087
01088 #ifdef TEST_HARNESS
01089 void main()
01090 {
01091 F32_CONTROL foo, getfoo;
01092
01093 S32_CONTROL bar, getbar;
01094
01095 BOOL_CONTROL baz;
01096
01097 U32 count = gGlobals.loadFromFile("controls.ini");
01098 llinfos << "Loaded " << count << " controls" << llendl;
01099
01100
01101 foo = new LLControlVariable<F32>("gFoo", 5.f, 1.f, 20.f);
01102 gGlobals.addEntry("gFoo", foo);
01103
01104 bar = new LLControlVariable<S32>("gBar", 10, 2, 22);
01105 gGlobals.addEntry("gBar", bar);
01106
01107 baz = new LLControlVariable<BOOL>("gBaz", FALSE);
01108 gGlobals.addEntry("gBaz", baz);
01109
01110
01111 getfoo = (LLControlVariable<F32>*) gGlobals.resolveName("gFoo");
01112 getfoo->dump();
01113
01114 getbar = (S32_CONTROL) gGlobals.resolveName("gBar");
01115 getbar->dump();
01116
01117
01118 getfoo->set(10.f);
01119 getfoo->dump();
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134 getfoo = (F32_CONTROL) gGlobals.resolveName("gFoo");
01135 getfoo->set(TRUE);
01136 getfoo->dump();
01137
01138
01139
01140
01141
01142
01143 delete foo;
01144 delete bar;
01145 delete baz;
01146 }
01147 #endif
01148
01149