llcontrol.cpp

Go to the documentation of this file.
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 //this defines the current version of the settings file
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                 // no-op
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         //Push back versus setValue'ing here, since we don't want to call a signal yet
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         // If we're going to save this value, return to default but don't fire
00121                 resetToDefault(false);
00122             if (llsd_compare(mValues.back(), value) == FALSE)
00123             {
00124                     mValues.push_back(value);
00125             }
00126         }
00127     else
00128     {
00129         // This is a unsaved value. Its needs to reside at
00130         // mValues[2] (or greater). It must not affect 
00131         // the result of getSaveValue()
00132             if (llsd_compare(mValues.back(), value) == FALSE)
00133             {
00134             while(mValues.size() > 2)
00135             {
00136                 // Remove any unsaved values.
00137                 mValues.pop_back();
00138             }
00139 
00140             if(mValues.size() < 2)
00141             {
00142                 // Add the default to the 'save' value.
00143                 mValues.push_back(mValues[0]);
00144             }
00145 
00146             // Add the 'un-save' value.
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         //The first setting is always the default
00160         //Pop to it and fire off the listener
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         //The first level of the stack is default
00174         //We assume that the second level is user preferences that should be saved
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         // if not, create the control and add it to the name table
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 // Set functions
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 // Load and save
00701 //---------------------------------------------------------------
00702 
00703 // Returns number of controls loaded, so 0 if failure
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         // Check file version
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                         // Declaration required, but this name not declared.
00746                         // Complain about non-empty names.
00747                         if (!name.empty())
00748                         {
00749                                 //read in to end of line
00750                                 llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
00751                         }
00752                         child_nodep = rootp->getNextChild();
00753                         continue;
00754                 }
00755 
00756                 // Got an item.  Load it up.
00757                 item++;
00758 
00759                 // If not declared, assume it's a string
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                 // Control name has been declared in code.
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                                 //RN: hack to support reading rectangles from a string
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                                 // Debug spam
00935                                 // llinfos << "Skipping " << control->getName() << llendl;
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         // This is a warning because sometime we want to use settings files which can't be written...
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                 // If the control exists just set the value from the input file.
00991                 LLControlVariable* existing_control = getControl(name);
00992                 if(existing_control)
00993                 {
00994                         // Check persistence. If not persisted, we shouldn't be loading.
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 // First-use
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         // test insertion
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         // test retrieval
01111         getfoo = (LLControlVariable<F32>*) gGlobals.resolveName("gFoo");
01112         getfoo->dump();
01113 
01114         getbar = (S32_CONTROL) gGlobals.resolveName("gBar");
01115         getbar->dump();
01116 
01117         // change data
01118         getfoo->set(10.f);
01119         getfoo->dump();
01120 
01121         // Failure modes
01122 
01123         // ...min > max
01124         // badfoo = new LLControlVariable<F32>("gFoo2", 100.f, 20.f, 5.f);
01125 
01126         // ...initial > max
01127         // badbar = new LLControlVariable<S32>("gBar2", 10, 20, 100000);
01128 
01129         // ...misspelled name
01130         // getfoo = (F32_CONTROL) gGlobals.resolveName("fooMisspelled");
01131         // getfoo->dump();
01132 
01133         // ...invalid data type
01134         getfoo = (F32_CONTROL) gGlobals.resolveName("gFoo");
01135         getfoo->set(TRUE);
01136         getfoo->dump();
01137 
01138         // ...out of range data
01139         // getfoo->set(100000000.f);
01140         // getfoo->dump();
01141 
01142         // Clean Up
01143         delete foo;
01144         delete bar;
01145         delete baz;
01146 }
01147 #endif
01148 
01149 

Generated on Fri May 16 08:33:05 2008 for SecondLife by  doxygen 1.5.5