diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llxml/llcontrol.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llxml/llcontrol.cpp')
-rw-r--r-- | linden/indra/llxml/llcontrol.cpp | 1420 |
1 files changed, 1420 insertions, 0 deletions
diff --git a/linden/indra/llxml/llcontrol.cpp b/linden/indra/llxml/llcontrol.cpp new file mode 100644 index 0000000..79fd522 --- /dev/null +++ b/linden/indra/llxml/llcontrol.cpp | |||
@@ -0,0 +1,1420 @@ | |||
1 | /** | ||
2 | * @file llcontrol.cpp | ||
3 | * @brief Holds global state for viewer. | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "linden_common.h" | ||
29 | |||
30 | #include <iostream> | ||
31 | #include <fstream> | ||
32 | #include <algorithm> | ||
33 | |||
34 | #include "llcontrol.h" | ||
35 | |||
36 | #include "llstl.h" | ||
37 | |||
38 | #include "linked_lists.h" | ||
39 | #include "llstring.h" | ||
40 | #include "v3math.h" | ||
41 | #include "v3dmath.h" | ||
42 | #include "v4coloru.h" | ||
43 | #include "v4color.h" | ||
44 | #include "v3color.h" | ||
45 | #include "llrect.h" | ||
46 | #include "llxmltree.h" | ||
47 | #include "llsdserialize.h" | ||
48 | |||
49 | #if LL_RELEASE_FOR_DOWNLOAD | ||
50 | #define CONTROL_ERRS llwarns | ||
51 | #else | ||
52 | #define CONTROL_ERRS llerrs | ||
53 | #endif | ||
54 | |||
55 | //this defines the current version of the settings file | ||
56 | U32 LLControlBase::sMaxControlNameLength = 0; | ||
57 | |||
58 | //These lists are used to store the ID's of registered event listeners. | ||
59 | std::list<S32> LLControlBase::mFreeIDs; | ||
60 | std::list<S32> LLControlBase::mUsedIDs; | ||
61 | |||
62 | S32 LLControlBase::mTopID; | ||
63 | |||
64 | std::set<LLControlBase*> LLControlBase::mChangedControls; | ||
65 | |||
66 | const S32 CURRENT_VERSION = 101; | ||
67 | |||
68 | BOOL control_insert_before( LLControlBase* first, LLControlBase* second ); | ||
69 | |||
70 | BOOL LLControl::llsd_compare(const LLSD& a, const LLSD & b) | ||
71 | { | ||
72 | switch (mType) | ||
73 | { | ||
74 | case TYPE_U32: | ||
75 | case TYPE_S32: | ||
76 | return a.asInteger() == b.asInteger(); | ||
77 | case TYPE_BOOLEAN: | ||
78 | return a.asBoolean() == b.asBoolean(); | ||
79 | case TYPE_F32: | ||
80 | return a.asReal() == b.asReal(); | ||
81 | case TYPE_VEC3: | ||
82 | case TYPE_VEC3D: | ||
83 | return LLVector3d(a) == LLVector3d(b); | ||
84 | case TYPE_RECT: | ||
85 | return LLRect(a) == LLRect(b); | ||
86 | case TYPE_COL4: | ||
87 | return LLColor4(a) == LLColor4(b); | ||
88 | case TYPE_COL3: | ||
89 | return LLColor3(a) == LLColor3(b); | ||
90 | case TYPE_COL4U: | ||
91 | return LLColor4U(a) == LLColor4U(b); | ||
92 | case TYPE_STRING: | ||
93 | return a.asString() == b.asString(); | ||
94 | default: | ||
95 | // no-op | ||
96 | break; | ||
97 | } | ||
98 | |||
99 | return FALSE; | ||
100 | } | ||
101 | |||
102 | LLControlBase::~LLControlBase() | ||
103 | { | ||
104 | } | ||
105 | |||
106 | // virtual | ||
107 | void LLControlBase::resetToDefault() | ||
108 | { | ||
109 | } | ||
110 | |||
111 | LLControlGroup::LLControlGroup(): mNameTable() | ||
112 | { | ||
113 | //mFreeStringOffset = 0; | ||
114 | } | ||
115 | |||
116 | LLControlGroup::~LLControlGroup() | ||
117 | { | ||
118 | } | ||
119 | |||
120 | LLSD LLControlBase::registerListener(LLSimpleListenerObservable *listener, LLSD userdata) | ||
121 | { | ||
122 | // Symmetric listener relationship | ||
123 | addListener(listener, "", userdata); | ||
124 | listener->addListener(this, "", userdata); | ||
125 | return getValue(); | ||
126 | } | ||
127 | |||
128 | void LLControlGroup::cleanup() | ||
129 | { | ||
130 | mNameTable.clear(); | ||
131 | } | ||
132 | |||
133 | LLControlBase* LLControlGroup::getControl(const LLString& name) | ||
134 | { | ||
135 | return mNameTable[name]; | ||
136 | } | ||
137 | |||
138 | BOOL LLControlGroup::declareControl(const LLString& name, eControlType type, const LLSD initial_val, const LLString& comment, BOOL persist) | ||
139 | { | ||
140 | if(!mNameTable[name]) | ||
141 | { | ||
142 | // if not, create the control and add it to the name table | ||
143 | LLControl* control = new LLControl(name, type, initial_val, comment, persist); | ||
144 | mNameTable[name] = control; | ||
145 | return TRUE; | ||
146 | } else | ||
147 | { | ||
148 | llwarns << "LLControlGroup::declareControl: Control named " << name << " already exists." << llendl; | ||
149 | return FALSE; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | BOOL LLControlGroup::declareU32(const LLString& name, const U32 initial_val, const LLString& comment, BOOL persist) | ||
154 | { | ||
155 | return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist); | ||
156 | } | ||
157 | |||
158 | BOOL LLControlGroup::declareS32(const LLString& name, const S32 initial_val, const LLString& comment, BOOL persist) | ||
159 | { | ||
160 | return declareControl(name, TYPE_S32, initial_val, comment, persist); | ||
161 | } | ||
162 | |||
163 | BOOL LLControlGroup::declareF32(const LLString& name, const F32 initial_val, const LLString& comment, BOOL persist) | ||
164 | { | ||
165 | return declareControl(name, TYPE_F32, initial_val, comment, persist); | ||
166 | } | ||
167 | |||
168 | BOOL LLControlGroup::declareBOOL(const LLString& name, const BOOL initial_val, const LLString& comment, BOOL persist) | ||
169 | { | ||
170 | return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist); | ||
171 | } | ||
172 | |||
173 | BOOL LLControlGroup::declareString(const LLString& name, const LLString& initial_val, const LLString& comment, BOOL persist) | ||
174 | { | ||
175 | return declareControl(name, TYPE_STRING, initial_val, comment, persist); | ||
176 | } | ||
177 | |||
178 | BOOL LLControlGroup::declareVec3(const LLString& name, const LLVector3 &initial_val, const LLString& comment, BOOL persist) | ||
179 | { | ||
180 | return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist); | ||
181 | } | ||
182 | |||
183 | BOOL LLControlGroup::declareVec3d(const LLString& name, const LLVector3d &initial_val, const LLString& comment, BOOL persist) | ||
184 | { | ||
185 | return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist); | ||
186 | } | ||
187 | |||
188 | BOOL LLControlGroup::declareRect(const LLString& name, const LLRect &initial_val, const LLString& comment, BOOL persist) | ||
189 | { | ||
190 | return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist); | ||
191 | } | ||
192 | |||
193 | BOOL LLControlGroup::declareColor4U(const LLString& name, const LLColor4U &initial_val, const LLString& comment, BOOL persist ) | ||
194 | { | ||
195 | return declareControl(name, TYPE_COL4U, initial_val.getValue(), comment, persist); | ||
196 | } | ||
197 | |||
198 | BOOL LLControlGroup::declareColor4(const LLString& name, const LLColor4 &initial_val, const LLString& comment, BOOL persist ) | ||
199 | { | ||
200 | return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist); | ||
201 | } | ||
202 | |||
203 | BOOL LLControlGroup::declareColor3(const LLString& name, const LLColor3 &initial_val, const LLString& comment, BOOL persist ) | ||
204 | { | ||
205 | return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist); | ||
206 | } | ||
207 | |||
208 | LLSD LLControlGroup::registerListener(const LLString& name, LLSimpleListenerObservable *listener) | ||
209 | { | ||
210 | LLControlBase *control = mNameTable[name]; | ||
211 | if (control) | ||
212 | { | ||
213 | return control->registerListener(listener); | ||
214 | } | ||
215 | return LLSD(); | ||
216 | } | ||
217 | |||
218 | BOOL LLControlGroup::getBOOL(const LLString& name) | ||
219 | { | ||
220 | LLControlBase* control = mNameTable[name]; | ||
221 | |||
222 | if (control && control->isType(TYPE_BOOLEAN)) | ||
223 | return control->get().asBoolean(); | ||
224 | else | ||
225 | { | ||
226 | CONTROL_ERRS << "Invalid BOOL control " << name << llendl; | ||
227 | return FALSE; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | S32 LLControlGroup::getS32(const LLString& name) | ||
232 | { | ||
233 | LLControlBase* control = mNameTable[name]; | ||
234 | |||
235 | if (control && control->isType(TYPE_S32)) | ||
236 | return control->get().asInteger(); | ||
237 | else | ||
238 | { | ||
239 | CONTROL_ERRS << "Invalid S32 control " << name << llendl; | ||
240 | return 0; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | U32 LLControlGroup::getU32(const LLString& name) | ||
245 | { | ||
246 | LLControlBase* control = mNameTable[name]; | ||
247 | |||
248 | if (control && control->isType(TYPE_U32)) | ||
249 | return control->get().asInteger(); | ||
250 | else | ||
251 | { | ||
252 | CONTROL_ERRS << "Invalid U32 control " << name << llendl; | ||
253 | return 0; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | F32 LLControlGroup::getF32(const LLString& name) | ||
258 | { | ||
259 | LLControlBase* control = mNameTable[name]; | ||
260 | |||
261 | if (control && control->isType(TYPE_F32)) | ||
262 | return (F32) control->get().asReal(); | ||
263 | else | ||
264 | { | ||
265 | CONTROL_ERRS << "Invalid F32 control " << name << llendl; | ||
266 | return 0.0f; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | LLString LLControlGroup::findString(const LLString& name) | ||
271 | { | ||
272 | LLControlBase* control = mNameTable[name]; | ||
273 | |||
274 | if (control && control->isType(TYPE_STRING)) | ||
275 | return control->get().asString(); | ||
276 | return LLString::null; | ||
277 | } | ||
278 | |||
279 | LLString LLControlGroup::getString(const LLString& name) | ||
280 | { | ||
281 | LLControlBase* control = mNameTable[name]; | ||
282 | |||
283 | if (control && control->isType(TYPE_STRING)) | ||
284 | return control->get().asString(); | ||
285 | else | ||
286 | { | ||
287 | CONTROL_ERRS << "Invalid string control " << name << llendl; | ||
288 | return LLString::null; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | LLWString LLControlGroup::getWString(const LLString& name) | ||
293 | { | ||
294 | return utf8str_to_wstring(getString(name)); | ||
295 | } | ||
296 | |||
297 | LLString LLControlGroup::getText(const LLString& name) | ||
298 | { | ||
299 | LLString utf8_string = getString(name); | ||
300 | LLString::replaceChar(utf8_string, '^', '\n'); | ||
301 | LLString::replaceChar(utf8_string, '%', ' '); | ||
302 | return (utf8_string); | ||
303 | } | ||
304 | |||
305 | LLVector3 LLControlGroup::getVector3(const LLString& name) | ||
306 | { | ||
307 | LLControlBase* control = mNameTable[name]; | ||
308 | |||
309 | if (control && control->isType(TYPE_VEC3)) | ||
310 | return control->get(); | ||
311 | else | ||
312 | { | ||
313 | CONTROL_ERRS << "Invalid LLVector3 control " << name << llendl; | ||
314 | return LLVector3::zero; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | LLVector3d LLControlGroup::getVector3d(const LLString& name) | ||
319 | { | ||
320 | LLControlBase* control = mNameTable[name]; | ||
321 | |||
322 | if (control && control->isType(TYPE_VEC3D)) | ||
323 | return control->get(); | ||
324 | else | ||
325 | { | ||
326 | CONTROL_ERRS << "Invalid LLVector3d control " << name << llendl; | ||
327 | return LLVector3d::zero; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | LLRect LLControlGroup::getRect(const LLString& name) | ||
332 | { | ||
333 | LLControlBase* control = mNameTable[name]; | ||
334 | |||
335 | if (control && control->isType(TYPE_RECT)) | ||
336 | return control->get(); | ||
337 | else | ||
338 | { | ||
339 | CONTROL_ERRS << "Invalid rect control " << name << llendl; | ||
340 | return LLRect::null; | ||
341 | } | ||
342 | } | ||
343 | |||
344 | |||
345 | LLColor4 LLControlGroup::getColor(const LLString& name) | ||
346 | { | ||
347 | ctrl_name_table_t::const_iterator i = mNameTable.find(name); | ||
348 | |||
349 | if (i != mNameTable.end()) | ||
350 | { | ||
351 | LLControlBase* control = i->second; | ||
352 | |||
353 | switch(control->mType) | ||
354 | { | ||
355 | case TYPE_COL4: | ||
356 | { | ||
357 | return LLColor4(control->get()); | ||
358 | } | ||
359 | case TYPE_COL4U: | ||
360 | { | ||
361 | return LLColor4(LLColor4U(control->get())); | ||
362 | } | ||
363 | default: | ||
364 | { | ||
365 | CONTROL_ERRS << "Control " << name << " not a color" << llendl; | ||
366 | return LLColor4::white; | ||
367 | } | ||
368 | } | ||
369 | } | ||
370 | else | ||
371 | { | ||
372 | CONTROL_ERRS << "Invalid getColor control " << name << llendl; | ||
373 | return LLColor4::white; | ||
374 | } | ||
375 | } | ||
376 | |||
377 | LLColor4U LLControlGroup::getColor4U(const LLString& name) | ||
378 | { | ||
379 | LLControlBase* control = mNameTable[name]; | ||
380 | |||
381 | if (control && control->isType(TYPE_COL4U)) | ||
382 | return control->get(); | ||
383 | else | ||
384 | { | ||
385 | CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl; | ||
386 | return LLColor4U::white; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | LLColor4 LLControlGroup::getColor4(const LLString& name) | ||
391 | { | ||
392 | LLControlBase* control = mNameTable[name]; | ||
393 | |||
394 | if (control && control->isType(TYPE_COL4)) | ||
395 | return control->get(); | ||
396 | else | ||
397 | { | ||
398 | CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl; | ||
399 | return LLColor4::white; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | LLColor3 LLControlGroup::getColor3(const LLString& name) | ||
404 | { | ||
405 | LLControlBase* control = mNameTable[name]; | ||
406 | |||
407 | if (control && control->isType(TYPE_COL3)) | ||
408 | return control->get(); | ||
409 | else | ||
410 | { | ||
411 | CONTROL_ERRS << "Invalid LLColor3 control " << name << llendl; | ||
412 | return LLColor3::white; | ||
413 | } | ||
414 | } | ||
415 | |||
416 | BOOL LLControlGroup::controlExists(const LLString& name) | ||
417 | { | ||
418 | void *control = mNameTable[name]; | ||
419 | |||
420 | return (control != 0); | ||
421 | } | ||
422 | |||
423 | //------------------------------------------------------------------- | ||
424 | // Set functions | ||
425 | //------------------------------------------------------------------- | ||
426 | |||
427 | void LLControlGroup::setBOOL(const LLString& name, BOOL val) | ||
428 | { | ||
429 | LLControlBase* control = mNameTable[name]; | ||
430 | |||
431 | if (control && control->isType(TYPE_BOOLEAN)) | ||
432 | { | ||
433 | control->set(val); | ||
434 | } | ||
435 | else | ||
436 | { | ||
437 | CONTROL_ERRS << "Invalid control " << name << llendl; | ||
438 | } | ||
439 | } | ||
440 | |||
441 | |||
442 | void LLControlGroup::setS32(const LLString& name, S32 val) | ||
443 | { | ||
444 | LLControlBase* control = mNameTable[name]; | ||
445 | |||
446 | if (control && control->isType(TYPE_S32)) | ||
447 | { | ||
448 | control->set(val); | ||
449 | } | ||
450 | else | ||
451 | { | ||
452 | CONTROL_ERRS << "Invalid control " << name << llendl; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | |||
457 | void LLControlGroup::setF32(const LLString& name, F32 val) | ||
458 | { | ||
459 | LLControlBase* control = mNameTable[name]; | ||
460 | |||
461 | if (control && control->isType(TYPE_F32)) | ||
462 | { | ||
463 | control->set(val); | ||
464 | } | ||
465 | else | ||
466 | { | ||
467 | CONTROL_ERRS << "Invalid control " << name << llendl; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | |||
472 | void LLControlGroup::setU32(const LLString& name, U32 val) | ||
473 | { | ||
474 | LLControlBase* control = mNameTable[name]; | ||
475 | |||
476 | if (control && control->isType(TYPE_U32)) | ||
477 | { | ||
478 | control->set((LLSD::Integer) val); | ||
479 | } | ||
480 | else | ||
481 | { | ||
482 | CONTROL_ERRS << "Invalid control " << name << llendl; | ||
483 | } | ||
484 | } | ||
485 | |||
486 | |||
487 | void LLControlGroup::setString(const LLString& name, const LLString &val) | ||
488 | { | ||
489 | LLControlBase* control = mNameTable[name]; | ||
490 | |||
491 | if (control && control->isType(TYPE_STRING)) | ||
492 | { | ||
493 | control->set(val); | ||
494 | } | ||
495 | else | ||
496 | { | ||
497 | CONTROL_ERRS << "Invalid control " << name << llendl; | ||
498 | } | ||
499 | } | ||
500 | |||
501 | |||
502 | void LLControlGroup::setVector3(const LLString& name, const LLVector3 &val) | ||
503 | { | ||
504 | LLControlBase* control = mNameTable[name]; | ||
505 | |||
506 | if (control && control->isType(TYPE_VEC3)) | ||
507 | { | ||
508 | control->set(val.getValue()); | ||
509 | } | ||
510 | else | ||
511 | { | ||
512 | CONTROL_ERRS << "Invalid control " << name << llendl; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | void LLControlGroup::setVector3d(const LLString& name, const LLVector3d &val) | ||
517 | { | ||
518 | LLControlBase* control = mNameTable[name]; | ||
519 | |||
520 | if (control && control->isType(TYPE_VEC3D)) | ||
521 | { | ||
522 | control->set(val.getValue()); | ||
523 | } | ||
524 | else | ||
525 | { | ||
526 | CONTROL_ERRS << "Invalid control " << name << llendl; | ||
527 | } | ||
528 | } | ||
529 | |||
530 | void LLControlGroup::setRect(const LLString& name, const LLRect &val) | ||
531 | { | ||
532 | LLControlBase* control = mNameTable[name]; | ||
533 | |||
534 | if (control && control->isType(TYPE_RECT)) | ||
535 | { | ||
536 | control->set(val.getValue()); | ||
537 | } | ||
538 | else | ||
539 | { | ||
540 | CONTROL_ERRS << "Invalid rect control " << name << llendl; | ||
541 | } | ||
542 | } | ||
543 | |||
544 | void LLControlGroup::setColor4U(const LLString& name, const LLColor4U &val) | ||
545 | { | ||
546 | LLControlBase* control = mNameTable[name]; | ||
547 | |||
548 | if (control && control->isType(TYPE_COL4U)) | ||
549 | { | ||
550 | control->set(val.getValue()); | ||
551 | } | ||
552 | else | ||
553 | { | ||
554 | CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | void LLControlGroup::setColor4(const LLString& name, const LLColor4 &val) | ||
559 | { | ||
560 | LLControlBase* control = mNameTable[name]; | ||
561 | |||
562 | if (control && control->isType(TYPE_COL4)) | ||
563 | { | ||
564 | control->set(val.getValue()); | ||
565 | } | ||
566 | else | ||
567 | { | ||
568 | CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl; | ||
569 | } | ||
570 | } | ||
571 | |||
572 | void LLControlGroup::setValue(const LLString& name, const LLSD& val) | ||
573 | { | ||
574 | if (name.empty()) | ||
575 | { | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | LLControlBase* control = mNameTable[name]; | ||
580 | |||
581 | if (control) | ||
582 | { | ||
583 | control->set(val); | ||
584 | } | ||
585 | else | ||
586 | { | ||
587 | CONTROL_ERRS << "Invalid control " << name << llendl; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | //--------------------------------------------------------------- | ||
592 | // Load and save | ||
593 | //--------------------------------------------------------------- | ||
594 | |||
595 | U32 LLControlGroup::loadFromFileLegacy(const LLString& filename, BOOL require_declaration, eControlType declare_as) | ||
596 | { | ||
597 | U32 item = 0; | ||
598 | U32 validitems = 0; | ||
599 | llifstream file; | ||
600 | S32 version; | ||
601 | |||
602 | file.open(filename.c_str()); | ||
603 | |||
604 | if (!file) | ||
605 | { | ||
606 | llinfos << "LLControlGroup::loadFromFile unable to open." << llendl; | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | // Check file version | ||
611 | LLString name; | ||
612 | file >> name; | ||
613 | file >> version; | ||
614 | if (name != "version" || version != CURRENT_VERSION) | ||
615 | { | ||
616 | llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl; | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | while (!file.eof()) | ||
621 | { | ||
622 | file >> name; | ||
623 | |||
624 | if (name.empty()) | ||
625 | { | ||
626 | continue; | ||
627 | } | ||
628 | |||
629 | if (name.substr(0,2) == "//") | ||
630 | { | ||
631 | // This is a comment. | ||
632 | char buffer[MAX_STRING]; | ||
633 | file.getline(buffer, MAX_STRING); | ||
634 | continue; | ||
635 | } | ||
636 | |||
637 | BOOL declared = mNameTable.find(name) != mNameTable.end(); | ||
638 | |||
639 | if (require_declaration && !declared) | ||
640 | { | ||
641 | // Declaration required, but this name not declared. | ||
642 | // Complain about non-empty names. | ||
643 | if (!name.empty()) | ||
644 | { | ||
645 | //read in to end of line | ||
646 | char buffer[MAX_STRING]; | ||
647 | file.getline(buffer, MAX_STRING); | ||
648 | llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl; | ||
649 | } | ||
650 | continue; | ||
651 | } | ||
652 | |||
653 | // Got an item. Load it up. | ||
654 | item++; | ||
655 | |||
656 | // If not declared, assume it's a string | ||
657 | if (!declared) | ||
658 | { | ||
659 | switch(declare_as) | ||
660 | { | ||
661 | case TYPE_COL4: | ||
662 | declareColor4(name, LLColor4::white, LLString::null, NO_PERSIST); | ||
663 | break; | ||
664 | case TYPE_COL4U: | ||
665 | declareColor4U(name, LLColor4U::white, LLString::null, NO_PERSIST); | ||
666 | break; | ||
667 | case TYPE_STRING: | ||
668 | default: | ||
669 | declareString(name, LLString::null, LLString::null, NO_PERSIST); | ||
670 | break; | ||
671 | } | ||
672 | } | ||
673 | |||
674 | // Control name has been declared in code. | ||
675 | LLControlBase *control = getControl(name); | ||
676 | |||
677 | llassert(control); | ||
678 | |||
679 | switch(control->mType) | ||
680 | { | ||
681 | case TYPE_F32: | ||
682 | { | ||
683 | F32 initial; | ||
684 | |||
685 | file >> initial; | ||
686 | |||
687 | control->set(initial); | ||
688 | validitems++; | ||
689 | } | ||
690 | break; | ||
691 | case TYPE_S32: | ||
692 | { | ||
693 | S32 initial; | ||
694 | |||
695 | file >> initial; | ||
696 | |||
697 | control->set(initial); | ||
698 | validitems++; | ||
699 | } | ||
700 | break; | ||
701 | case TYPE_U32: | ||
702 | { | ||
703 | U32 initial; | ||
704 | |||
705 | file >> initial; | ||
706 | control->set((LLSD::Integer) initial); | ||
707 | validitems++; | ||
708 | } | ||
709 | break; | ||
710 | case TYPE_BOOLEAN: | ||
711 | { | ||
712 | char boolstring[256]; | ||
713 | BOOL valid = FALSE; | ||
714 | BOOL initial = FALSE; | ||
715 | |||
716 | file >> boolstring; | ||
717 | if (!strcmp("TRUE", boolstring)) | ||
718 | { | ||
719 | initial = TRUE; | ||
720 | valid = TRUE; | ||
721 | } | ||
722 | else if (!strcmp("FALSE", boolstring)) | ||
723 | { | ||
724 | initial = FALSE; | ||
725 | valid = TRUE; | ||
726 | } | ||
727 | |||
728 | if (valid) | ||
729 | { | ||
730 | control->set(initial); | ||
731 | } | ||
732 | else | ||
733 | { | ||
734 | llinfos << filename << "Item " << item << ": Invalid BOOL control " << name << ", " << boolstring << llendl; | ||
735 | } | ||
736 | |||
737 | validitems++; | ||
738 | } | ||
739 | break; | ||
740 | case TYPE_STRING: | ||
741 | { | ||
742 | LLString string; | ||
743 | |||
744 | file >> string; | ||
745 | |||
746 | control->set(string); | ||
747 | validitems++; | ||
748 | } | ||
749 | break; | ||
750 | case TYPE_VEC3: | ||
751 | { | ||
752 | F32 x, y, z; | ||
753 | |||
754 | file >> x >> y >> z; | ||
755 | |||
756 | LLVector3 vector(x, y, z); | ||
757 | |||
758 | control->set(vector.getValue()); | ||
759 | validitems++; | ||
760 | } | ||
761 | break; | ||
762 | case TYPE_VEC3D: | ||
763 | { | ||
764 | F64 x, y, z; | ||
765 | |||
766 | file >> x >> y >> z; | ||
767 | |||
768 | LLVector3d vector(x, y, z); | ||
769 | |||
770 | control->set(vector.getValue()); | ||
771 | validitems++; | ||
772 | } | ||
773 | break; | ||
774 | case TYPE_RECT: | ||
775 | { | ||
776 | S32 left, bottom, width, height; | ||
777 | |||
778 | file >> left >> bottom >> width >> height; | ||
779 | |||
780 | LLRect rect; | ||
781 | rect.setOriginAndSize(left, bottom, width, height); | ||
782 | |||
783 | control->set(rect.getValue()); | ||
784 | validitems++; | ||
785 | } | ||
786 | break; | ||
787 | case TYPE_COL4U: | ||
788 | { | ||
789 | S32 red, green, blue, alpha; | ||
790 | LLColor4U color; | ||
791 | file >> red >> green >> blue >> alpha; | ||
792 | color.setVec(red, green, blue, alpha); | ||
793 | control->set(color.getValue()); | ||
794 | validitems++; | ||
795 | } | ||
796 | break; | ||
797 | case TYPE_COL4: | ||
798 | { | ||
799 | LLColor4 color; | ||
800 | file >> color.mV[VRED] >> color.mV[VGREEN] | ||
801 | >> color.mV[VBLUE] >> color.mV[VALPHA]; | ||
802 | control->set(color.getValue()); | ||
803 | validitems++; | ||
804 | } | ||
805 | break; | ||
806 | case TYPE_COL3: | ||
807 | { | ||
808 | LLColor3 color; | ||
809 | file >> color.mV[VRED] >> color.mV[VGREEN] | ||
810 | >> color.mV[VBLUE]; | ||
811 | control->set(color.getValue()); | ||
812 | validitems++; | ||
813 | } | ||
814 | break; | ||
815 | } | ||
816 | } | ||
817 | |||
818 | file.close(); | ||
819 | |||
820 | return validitems; | ||
821 | } | ||
822 | |||
823 | // Returns number of controls loaded, so 0 if failure | ||
824 | U32 LLControlGroup::loadFromFile(const LLString& filename, BOOL require_declaration, eControlType declare_as) | ||
825 | { | ||
826 | LLString name; | ||
827 | |||
828 | LLXmlTree xml_controls; | ||
829 | |||
830 | if (!xml_controls.parseFile(filename)) | ||
831 | { | ||
832 | llwarns << "Unable to open control file " << filename << llendl; | ||
833 | return 0; | ||
834 | } | ||
835 | |||
836 | LLXmlTreeNode* rootp = xml_controls.getRoot(); | ||
837 | if (!rootp || !rootp->hasAttribute("version")) | ||
838 | { | ||
839 | llwarns << "No valid settings header found in control file " << filename << llendl; | ||
840 | return 0; | ||
841 | } | ||
842 | |||
843 | U32 item = 0; | ||
844 | U32 validitems = 0; | ||
845 | S32 version; | ||
846 | |||
847 | rootp->getAttributeS32("version", version); | ||
848 | |||
849 | // Check file version | ||
850 | if (version != CURRENT_VERSION) | ||
851 | { | ||
852 | llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl; | ||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | LLXmlTreeNode* child_nodep = rootp->getFirstChild(); | ||
857 | while(child_nodep) | ||
858 | { | ||
859 | name = child_nodep->getName(); | ||
860 | |||
861 | BOOL declared = (mNameTable[name].notNull()); | ||
862 | |||
863 | if (require_declaration && !declared) | ||
864 | { | ||
865 | // Declaration required, but this name not declared. | ||
866 | // Complain about non-empty names. | ||
867 | if (!name.empty()) | ||
868 | { | ||
869 | //read in to end of line | ||
870 | llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl; | ||
871 | } | ||
872 | child_nodep = rootp->getNextChild(); | ||
873 | continue; | ||
874 | } | ||
875 | |||
876 | // Got an item. Load it up. | ||
877 | item++; | ||
878 | |||
879 | // If not declared, assume it's a string | ||
880 | if (!declared) | ||
881 | { | ||
882 | switch(declare_as) | ||
883 | { | ||
884 | case TYPE_COL4: | ||
885 | declareColor4(name, LLColor4::white, "", NO_PERSIST); | ||
886 | break; | ||
887 | case TYPE_COL4U: | ||
888 | declareColor4U(name, LLColor4U::white, "", NO_PERSIST); | ||
889 | break; | ||
890 | case TYPE_STRING: | ||
891 | default: | ||
892 | declareString(name, LLString::null, "", NO_PERSIST); | ||
893 | break; | ||
894 | } | ||
895 | } | ||
896 | |||
897 | // Control name has been declared in code. | ||
898 | LLControlBase *control = getControl(name); | ||
899 | |||
900 | llassert(control); | ||
901 | |||
902 | switch(control->mType) | ||
903 | { | ||
904 | case TYPE_F32: | ||
905 | { | ||
906 | F32 initial = 0.f; | ||
907 | |||
908 | child_nodep->getAttributeF32("value", initial); | ||
909 | |||
910 | control->set(initial); | ||
911 | validitems++; | ||
912 | } | ||
913 | break; | ||
914 | case TYPE_S32: | ||
915 | { | ||
916 | S32 initial = 0; | ||
917 | |||
918 | child_nodep->getAttributeS32("value", initial); | ||
919 | |||
920 | control->set(initial); | ||
921 | validitems++; | ||
922 | } | ||
923 | break; | ||
924 | case TYPE_U32: | ||
925 | { | ||
926 | U32 initial = 0; | ||
927 | child_nodep->getAttributeU32("value", initial); | ||
928 | control->set((LLSD::Integer) initial); | ||
929 | validitems++; | ||
930 | } | ||
931 | break; | ||
932 | case TYPE_BOOLEAN: | ||
933 | { | ||
934 | BOOL initial = FALSE; | ||
935 | |||
936 | child_nodep->getAttributeBOOL("value", initial); | ||
937 | control->set(initial); | ||
938 | |||
939 | validitems++; | ||
940 | } | ||
941 | break; | ||
942 | case TYPE_STRING: | ||
943 | { | ||
944 | LLString string; | ||
945 | child_nodep->getAttributeString("value", string); | ||
946 | if (string == LLString::null) | ||
947 | { | ||
948 | string = ""; | ||
949 | } | ||
950 | control->set(string); | ||
951 | validitems++; | ||
952 | } | ||
953 | break; | ||
954 | case TYPE_VEC3: | ||
955 | { | ||
956 | LLVector3 vector; | ||
957 | |||
958 | child_nodep->getAttributeVector3("value", vector); | ||
959 | control->set(vector.getValue()); | ||
960 | validitems++; | ||
961 | } | ||
962 | break; | ||
963 | case TYPE_VEC3D: | ||
964 | { | ||
965 | LLVector3d vector; | ||
966 | |||
967 | child_nodep->getAttributeVector3d("value", vector); | ||
968 | |||
969 | control->set(vector.getValue()); | ||
970 | validitems++; | ||
971 | } | ||
972 | break; | ||
973 | case TYPE_RECT: | ||
974 | { | ||
975 | //RN: hack to support reading rectangles from a string | ||
976 | LLString rect_string; | ||
977 | |||
978 | child_nodep->getAttributeString("value", rect_string); | ||
979 | std::istringstream istream(rect_string); | ||
980 | S32 left, bottom, width, height; | ||
981 | |||
982 | istream >> left >> bottom >> width >> height; | ||
983 | |||
984 | LLRect rect; | ||
985 | rect.setOriginAndSize(left, bottom, width, height); | ||
986 | |||
987 | control->set(rect.getValue()); | ||
988 | validitems++; | ||
989 | } | ||
990 | break; | ||
991 | case TYPE_COL4U: | ||
992 | { | ||
993 | LLColor4U color; | ||
994 | |||
995 | child_nodep->getAttributeColor4U("value", color); | ||
996 | control->set(color.getValue()); | ||
997 | validitems++; | ||
998 | } | ||
999 | break; | ||
1000 | case TYPE_COL4: | ||
1001 | { | ||
1002 | LLColor4 color; | ||
1003 | |||
1004 | child_nodep->getAttributeColor4("value", color); | ||
1005 | control->set(color.getValue()); | ||
1006 | validitems++; | ||
1007 | } | ||
1008 | break; | ||
1009 | case TYPE_COL3: | ||
1010 | { | ||
1011 | LLVector3 color; | ||
1012 | |||
1013 | child_nodep->getAttributeVector3("value", color); | ||
1014 | control->set(LLColor3(color.mV).getValue()); | ||
1015 | validitems++; | ||
1016 | } | ||
1017 | break; | ||
1018 | } | ||
1019 | |||
1020 | child_nodep = rootp->getNextChild(); | ||
1021 | } | ||
1022 | |||
1023 | return validitems; | ||
1024 | } | ||
1025 | |||
1026 | |||
1027 | U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only) | ||
1028 | { | ||
1029 | const char ENDL = '\n'; | ||
1030 | |||
1031 | llinfos << "Saving settings to file: " << filename << llendl; | ||
1032 | |||
1033 | // place the objects in a temporary container that enforces a sort | ||
1034 | // order to ease manual editing of the file | ||
1035 | LLLinkedList< LLControlBase > controls; | ||
1036 | controls.setInsertBefore( &control_insert_before ); | ||
1037 | LLString name; | ||
1038 | for (ctrl_name_table_t::iterator iter = mNameTable.begin(); | ||
1039 | iter != mNameTable.end(); iter++) | ||
1040 | { | ||
1041 | name = iter->first; | ||
1042 | if (name.empty()) | ||
1043 | { | ||
1044 | CONTROL_ERRS << "Control with no name found!!!" << llendl; | ||
1045 | break; | ||
1046 | } | ||
1047 | |||
1048 | LLControlBase* control = (LLControlBase *)mNameTable[name]; | ||
1049 | |||
1050 | if (!control) | ||
1051 | { | ||
1052 | llwarns << "Tried to save invalid control: " << name << llendl; | ||
1053 | } | ||
1054 | |||
1055 | if( control && control->mPersist ) | ||
1056 | { | ||
1057 | if (!(nondefault_only && (control->mIsDefault))) | ||
1058 | { | ||
1059 | controls.addDataSorted( control ); | ||
1060 | } | ||
1061 | else | ||
1062 | { | ||
1063 | // Debug spam | ||
1064 | // llinfos << "Skipping " << control->getName() << llendl; | ||
1065 | } | ||
1066 | } | ||
1067 | } | ||
1068 | |||
1069 | llofstream file; | ||
1070 | file.open(filename.c_str()); | ||
1071 | |||
1072 | if (!file.is_open()) | ||
1073 | { | ||
1074 | // This is a warning because sometime we want to use settings files which can't be written... | ||
1075 | llwarns << "LLControlGroup::saveToFile unable to open file for writing" << llendl; | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | // Write file version | ||
1080 | file << "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n"; | ||
1081 | file << "<settings version = \"" << CURRENT_VERSION << "\">\n"; | ||
1082 | for( LLControlBase* control = controls.getFirstData(); | ||
1083 | control != NULL; | ||
1084 | control = controls.getNextData() ) | ||
1085 | { | ||
1086 | file << "\t<!--" << control->comment() << "-->" << ENDL; | ||
1087 | name = control->name(); | ||
1088 | switch (control->type()) | ||
1089 | { | ||
1090 | case TYPE_U32: | ||
1091 | { | ||
1092 | file << "\t<" << name << " value=\"" << (U32) control->get().asInteger() << "\"/>\n"; | ||
1093 | break; | ||
1094 | } | ||
1095 | case TYPE_S32: | ||
1096 | { | ||
1097 | file << "\t<" << name << " value=\"" << (S32) control->get().asInteger() << "\"/>\n"; | ||
1098 | break; | ||
1099 | } | ||
1100 | case TYPE_F32: | ||
1101 | { | ||
1102 | file << "\t<" << name << " value=\"" << (F32) control->get().asReal() << "\"/>\n"; | ||
1103 | break; | ||
1104 | } | ||
1105 | case TYPE_VEC3: | ||
1106 | { | ||
1107 | LLVector3 vector(control->get()); | ||
1108 | file << "\t<" << name << " value=\"" << vector.mV[VX] << " " << vector.mV[VY] << " " << vector.mV[VZ] << "\"/>\n"; | ||
1109 | break; | ||
1110 | } | ||
1111 | case TYPE_VEC3D: | ||
1112 | { | ||
1113 | LLVector3d vector(control->get()); | ||
1114 | file << "\t<" << name << " value=\"" << vector.mdV[VX] << " " << vector.mdV[VY] << " " << vector.mdV[VZ] << "\"/>\n"; | ||
1115 | break; | ||
1116 | } | ||
1117 | case TYPE_RECT: | ||
1118 | { | ||
1119 | LLRect rect(control->get()); | ||
1120 | file << "\t<" << name << " value=\"" << rect.mLeft << " " << rect.mBottom << " " << rect.getWidth() << " " << rect.getHeight() << "\"/>\n"; | ||
1121 | break; | ||
1122 | } | ||
1123 | case TYPE_COL4: | ||
1124 | { | ||
1125 | LLColor4 color(control->get()); | ||
1126 | file << "\t<" << name << " value=\"" << color.mV[VRED] << ", " << color.mV[VGREEN] << ", " << color.mV[VBLUE] << ", " << color.mV[VALPHA] << "\"/>\n"; | ||
1127 | break; | ||
1128 | } | ||
1129 | case TYPE_COL3: | ||
1130 | { | ||
1131 | LLColor3 color(control->get()); | ||
1132 | file << "\t<" << name << " value=\"" << color.mV[VRED] << ", " << color.mV[VGREEN] << ", " << color.mV[VBLUE] << "\"/>\n"; | ||
1133 | break; | ||
1134 | } | ||
1135 | case TYPE_BOOLEAN: | ||
1136 | { | ||
1137 | file << "\t<" << name << " value=\"" << (control->get().asBoolean() ? "TRUE" : "FALSE") << "\"/>\n"; | ||
1138 | break; | ||
1139 | } | ||
1140 | case TYPE_STRING: | ||
1141 | { | ||
1142 | file << "\t<" << name << " value=\"" << LLSDXMLFormatter::escapeString(control->get().asString()) << "\"/>\n"; | ||
1143 | break; | ||
1144 | } | ||
1145 | default: | ||
1146 | { | ||
1147 | CONTROL_ERRS << "LLControlGroup::saveToFile - unknown control type!" << llendl; | ||
1148 | break; | ||
1149 | } | ||
1150 | } | ||
1151 | |||
1152 | // Debug spam | ||
1153 | // llinfos << name << " " << control->getValue().asString() << llendl; | ||
1154 | }// next | ||
1155 | |||
1156 | file << "</settings>\n"; | ||
1157 | file.close(); | ||
1158 | |||
1159 | return controls.getLength(); | ||
1160 | } | ||
1161 | |||
1162 | void LLControlGroup::applyOverrides(const std::map<std::string, std::string>& overrides) | ||
1163 | { | ||
1164 | for (std::map<std::string, std::string>::const_iterator iter = overrides.begin(); | ||
1165 | iter != overrides.end(); ++iter) | ||
1166 | { | ||
1167 | const std::string& command = iter->first; | ||
1168 | const std::string& value = iter->second; | ||
1169 | LLControlBase* control = (LLControlBase *)mNameTable[command]; | ||
1170 | if (control) | ||
1171 | { | ||
1172 | switch(control->mType) | ||
1173 | { | ||
1174 | case TYPE_U32: | ||
1175 | control->set((LLSD::Integer)atof(value.c_str())); | ||
1176 | break; | ||
1177 | case TYPE_S32: | ||
1178 | control->set((S32)atof(value.c_str())); | ||
1179 | break; | ||
1180 | case TYPE_F32: | ||
1181 | control->set((F32)atof(value.c_str())); | ||
1182 | break; | ||
1183 | case TYPE_BOOLEAN: | ||
1184 | if (!LLString::compareInsensitive(value.c_str(), "TRUE")) | ||
1185 | { | ||
1186 | control->set(TRUE); | ||
1187 | } | ||
1188 | else if (!LLString::compareInsensitive(value.c_str(), "FALSE")) | ||
1189 | { | ||
1190 | control->set(FALSE); | ||
1191 | } | ||
1192 | else | ||
1193 | { | ||
1194 | control->set((BOOL)atof(value.c_str())); | ||
1195 | } | ||
1196 | break; | ||
1197 | case TYPE_STRING: | ||
1198 | control->set(value); | ||
1199 | break; | ||
1200 | // // *FIX: implement this given time and need. | ||
1201 | // case TYPE_UUID: | ||
1202 | // break; | ||
1203 | // we don't support command line overrides of vec3 or col4 | ||
1204 | // yet - requires parsing of multiple values | ||
1205 | case TYPE_VEC3: | ||
1206 | case TYPE_VEC3D: | ||
1207 | case TYPE_COL4: | ||
1208 | case TYPE_COL3: | ||
1209 | default: | ||
1210 | break; | ||
1211 | } | ||
1212 | } | ||
1213 | else | ||
1214 | { | ||
1215 | llinfos << "There is no control variable " << command << llendl; | ||
1216 | } | ||
1217 | } | ||
1218 | } | ||
1219 | |||
1220 | void LLControlGroup::resetToDefaults() | ||
1221 | { | ||
1222 | ctrl_name_table_t::iterator control_iter; | ||
1223 | for (control_iter = mNameTable.begin(); | ||
1224 | control_iter != mNameTable.end(); | ||
1225 | ++control_iter) | ||
1226 | { | ||
1227 | LLControlBase* control = (*control_iter).second; | ||
1228 | control->resetToDefault(); | ||
1229 | } | ||
1230 | } | ||
1231 | |||
1232 | //============================================================================ | ||
1233 | // FIrst-use | ||
1234 | |||
1235 | |||
1236 | void LLControlGroup::addWarning(const LLString& name) | ||
1237 | { | ||
1238 | LLString warnname = "Warn" + name; | ||
1239 | if(!mNameTable[warnname]) | ||
1240 | { | ||
1241 | LLString comment = LLString("Enables ") + name + LLString(" warning dialog"); | ||
1242 | declareBOOL(warnname, TRUE, comment); | ||
1243 | mWarnings.insert(warnname); | ||
1244 | } | ||
1245 | } | ||
1246 | |||
1247 | BOOL LLControlGroup::getWarning(const LLString& name) | ||
1248 | { | ||
1249 | LLString warnname = "Warn" + name; | ||
1250 | return getBOOL(warnname); | ||
1251 | } | ||
1252 | |||
1253 | void LLControlGroup::setWarning(const LLString& name, BOOL val) | ||
1254 | { | ||
1255 | LLString warnname = "Warn" + name; | ||
1256 | setBOOL(warnname, val); | ||
1257 | } | ||
1258 | |||
1259 | void LLControlGroup::resetWarnings() | ||
1260 | { | ||
1261 | for (std::set<LLString>::iterator iter = mWarnings.begin(); | ||
1262 | iter != mWarnings.end(); ++iter) | ||
1263 | { | ||
1264 | setBOOL(*iter, TRUE); | ||
1265 | } | ||
1266 | } | ||
1267 | |||
1268 | |||
1269 | |||
1270 | //============================================================================= | ||
1271 | // Listener ID generator/management | ||
1272 | |||
1273 | void LLControlBase::releaseListenerID(S32 id) | ||
1274 | { | ||
1275 | mFreeIDs.push_back(id); | ||
1276 | } | ||
1277 | |||
1278 | S32 LLControlBase::allocateListenerID() | ||
1279 | { | ||
1280 | if(mFreeIDs.size() == 0) | ||
1281 | { //Out of IDs so generate some new ones. | ||
1282 | for(int t=0;t<32;t++) | ||
1283 | { | ||
1284 | mFreeIDs.push_back(mTopID++); | ||
1285 | } | ||
1286 | } | ||
1287 | S32 rtn = mFreeIDs.front(); | ||
1288 | mFreeIDs.pop_front(); | ||
1289 | mUsedIDs.push_back(rtn); | ||
1290 | return rtn; | ||
1291 | } | ||
1292 | |||
1293 | bool LLControlBase::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
1294 | { | ||
1295 | if (event->desc() == "value_changed") | ||
1296 | { | ||
1297 | setValue(((LLValueChangedEvent*)(LLEvent*)event)->mValue); | ||
1298 | return TRUE; | ||
1299 | } | ||
1300 | return TRUE; | ||
1301 | } | ||
1302 | |||
1303 | void LLControlBase::firePropertyChanged() | ||
1304 | { | ||
1305 | LLValueChangedEvent *evt = new LLValueChangedEvent(this, getValue()); | ||
1306 | fireEvent(evt, ""); | ||
1307 | } | ||
1308 | |||
1309 | //============================================================================ | ||
1310 | // Used to add a listener callback that will be called on the frame that the controls value changes | ||
1311 | |||
1312 | S32 LLControl::addListener(LLControl::tListenerCallback* cbfn) | ||
1313 | { | ||
1314 | S32 id = allocateListenerID(); | ||
1315 | mListeners.push_back(cbfn); | ||
1316 | mListenerIDs.push_back( id ); | ||
1317 | return id; | ||
1318 | } | ||
1319 | |||
1320 | void LLControl::updateListeners() { | ||
1321 | LLControl::tPropertyChangedListIter iter = mChangeEvents.begin(); | ||
1322 | while(iter!=mChangeEvents.end()){ | ||
1323 | LLControl::tPropertyChangedEvent& evt = *iter; | ||
1324 | (*evt.mCBFN)(evt.mNewValue,evt.mID,*this); | ||
1325 | iter++; | ||
1326 | } | ||
1327 | mChangeEvents.clear(); | ||
1328 | } | ||
1329 | |||
1330 | //static | ||
1331 | void LLControlBase::updateAllListeners() | ||
1332 | { | ||
1333 | std::set< LLControlBase* >::iterator iter = mChangedControls.begin(); | ||
1334 | while(iter != mChangedControls.end()){ | ||
1335 | (*iter)->updateListeners(); | ||
1336 | iter++; | ||
1337 | } | ||
1338 | mChangedControls.clear(); | ||
1339 | } | ||
1340 | |||
1341 | LLControl::LLControl( | ||
1342 | const LLString& name, | ||
1343 | eControlType type, | ||
1344 | LLSD initial, | ||
1345 | const LLString& comment, | ||
1346 | BOOL persist) : | ||
1347 | LLControlBase(name, type, comment, persist), | ||
1348 | mCurrent(initial), | ||
1349 | mDefault(initial) | ||
1350 | { | ||
1351 | } | ||
1352 | |||
1353 | //============================================================================ | ||
1354 | |||
1355 | #ifdef TEST_HARNESS | ||
1356 | void main() | ||
1357 | { | ||
1358 | F32_CONTROL foo, getfoo; | ||
1359 | |||
1360 | S32_CONTROL bar, getbar; | ||
1361 | |||
1362 | BOOL_CONTROL baz; | ||
1363 | |||
1364 | U32 count = gGlobals.loadFromFile("controls.ini"); | ||
1365 | llinfos << "Loaded " << count << " controls" << llendl; | ||
1366 | |||
1367 | // test insertion | ||
1368 | foo = new LLControl<F32>("gFoo", 5.f, 1.f, 20.f); | ||
1369 | gGlobals.addEntry("gFoo", foo); | ||
1370 | |||
1371 | bar = new LLControl<S32>("gBar", 10, 2, 22); | ||
1372 | gGlobals.addEntry("gBar", bar); | ||
1373 | |||
1374 | baz = new LLControl<BOOL>("gBaz", FALSE); | ||
1375 | gGlobals.addEntry("gBaz", baz); | ||
1376 | |||
1377 | // test retrieval | ||
1378 | getfoo = (LLControl<F32>*) gGlobals.resolveName("gFoo"); | ||
1379 | getfoo->dump(); | ||
1380 | |||
1381 | getbar = (S32_CONTROL) gGlobals.resolveName("gBar"); | ||
1382 | getbar->dump(); | ||
1383 | |||
1384 | // change data | ||
1385 | getfoo->set(10.f); | ||
1386 | getfoo->dump(); | ||
1387 | |||
1388 | // Failure modes | ||
1389 | |||
1390 | // ...min > max | ||
1391 | // badfoo = new LLControl<F32>("gFoo2", 100.f, 20.f, 5.f); | ||
1392 | |||
1393 | // ...initial > max | ||
1394 | // badbar = new LLControl<S32>("gBar2", 10, 20, 100000); | ||
1395 | |||
1396 | // ...misspelled name | ||
1397 | // getfoo = (F32_CONTROL) gGlobals.resolveName("fooMisspelled"); | ||
1398 | // getfoo->dump(); | ||
1399 | |||
1400 | // ...invalid data type | ||
1401 | getfoo = (F32_CONTROL) gGlobals.resolveName("gFoo"); | ||
1402 | getfoo->set(TRUE); | ||
1403 | getfoo->dump(); | ||
1404 | |||
1405 | // ...out of range data | ||
1406 | // getfoo->set(100000000.f); | ||
1407 | // getfoo->dump(); | ||
1408 | |||
1409 | // Clean Up | ||
1410 | delete foo; | ||
1411 | delete bar; | ||
1412 | delete baz; | ||
1413 | } | ||
1414 | #endif | ||
1415 | |||
1416 | BOOL control_insert_before( LLControlBase* first, LLControlBase* second ) | ||
1417 | { | ||
1418 | return ( first->getName().compare(second->getName()) < 0 ); | ||
1419 | } | ||
1420 | |||