]> git.saurik.com Git - wxWidgets.git/blob - src/generic/prop.cpp
better centering of text/images
[wxWidgets.git] / src / generic / prop.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: prop.cpp
3 // Purpose: Propert sheet classes implementation
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "prop.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #include <ctype.h>
28 #include <stdlib.h>
29 #include <math.h>
30 #include <string.h>
31
32 #if wxUSE_IOSTREAMH
33 #if defined(__WXMSW__) && !defined(__GNUWIN32__)
34 #include <strstrea.h>
35 #else
36 #include <strstream.h>
37 #endif
38 #else
39 #include <strstream>
40 #endif
41
42 #include "wx/window.h"
43 #include "wx/utils.h"
44 #include "wx/list.h"
45 #include "wx/debug.h"
46 #include "wx/prop.h"
47
48 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValue, wxObject)
49
50 wxPropertyValue::wxPropertyValue(void)
51 {
52 m_type = wxPropertyValueNull;
53 m_next = NULL;
54 m_last = NULL;
55 m_value.first = NULL;
56 m_clientData = NULL;
57 m_modifiedFlag = FALSE;
58 }
59
60 wxPropertyValue::wxPropertyValue(const wxPropertyValue& copyFrom)
61 {
62 m_modifiedFlag = FALSE;
63 Copy((wxPropertyValue& )copyFrom);
64 }
65
66 wxPropertyValue::wxPropertyValue(const char *val)
67 {
68 m_modifiedFlag = FALSE;
69 m_type = wxPropertyValueString;
70
71 m_value.string = copystring(val);
72 m_clientData = NULL;
73 m_next = NULL;
74 m_last = NULL;
75 }
76
77 wxPropertyValue::wxPropertyValue(const wxString& val)
78 {
79 m_modifiedFlag = FALSE;
80 m_type = wxPropertyValueString;
81
82 m_value.string = copystring((const char *)val);
83 m_clientData = NULL;
84 m_next = NULL;
85 m_last = NULL;
86 }
87
88 wxPropertyValue::wxPropertyValue(long the_integer)
89 {
90 m_modifiedFlag = FALSE;
91 m_type = wxPropertyValueInteger;
92 m_value.integer = the_integer;
93 m_clientData = NULL;
94 m_next = NULL;
95 }
96
97 wxPropertyValue::wxPropertyValue(bool val)
98 {
99 m_modifiedFlag = FALSE;
100 m_type = wxPropertyValuebool;
101 m_value.integer = val;
102 m_clientData = NULL;
103 m_next = NULL;
104 }
105
106 wxPropertyValue::wxPropertyValue(float the_real)
107 {
108 m_modifiedFlag = FALSE;
109 m_type = wxPropertyValueReal;
110 m_value.real = the_real;
111 m_clientData = NULL;
112 m_next = NULL;
113 }
114
115 wxPropertyValue::wxPropertyValue(double the_real)
116 {
117 m_modifiedFlag = FALSE;
118 m_type = wxPropertyValueReal;
119 m_value.real = (float)the_real;
120 m_clientData = NULL;
121 m_next = NULL;
122 }
123
124 // Pointer versions: we have a pointer to the real C++ value.
125 wxPropertyValue::wxPropertyValue(char **val)
126 {
127 m_modifiedFlag = FALSE;
128 m_type = wxPropertyValueStringPtr;
129
130 m_value.stringPtr = val;
131 m_clientData = NULL;
132 m_next = NULL;
133 m_last = NULL;
134 }
135
136 wxPropertyValue::wxPropertyValue(long *val)
137 {
138 m_modifiedFlag = FALSE;
139 m_type = wxPropertyValueIntegerPtr;
140 m_value.integerPtr = val;
141 m_clientData = NULL;
142 m_next = NULL;
143 }
144
145 wxPropertyValue::wxPropertyValue(bool *val)
146 {
147 m_modifiedFlag = FALSE;
148 m_type = wxPropertyValueboolPtr;
149 m_value.boolPtr = val;
150 m_clientData = NULL;
151 m_next = NULL;
152 }
153
154 wxPropertyValue::wxPropertyValue(float *val)
155 {
156 m_modifiedFlag = FALSE;
157 m_type = wxPropertyValueRealPtr;
158 m_value.realPtr = val;
159 m_clientData = NULL;
160 m_next = NULL;
161 }
162
163 wxPropertyValue::wxPropertyValue(wxList *the_list)
164 {
165 m_modifiedFlag = FALSE;
166 m_type = wxPropertyValueList;
167 m_clientData = NULL;
168 m_last = NULL;
169 m_value.first = NULL;
170
171 wxNode *node = the_list->First();
172 while (node)
173 {
174 wxPropertyValue *expr = (wxPropertyValue *)node->Data();
175 Append(expr);
176 node = node->Next();
177 }
178
179 delete the_list;
180 }
181
182 wxPropertyValue::wxPropertyValue(wxStringList *the_list)
183 {
184 m_modifiedFlag = FALSE;
185 m_type = wxPropertyValueList;
186 m_clientData = NULL;
187 m_last = NULL;
188 m_value.first = NULL;
189
190 wxNode *node = the_list->First();
191 while (node)
192 {
193 char *s = (char *)node->Data();
194 Append(new wxPropertyValue(s));
195 node = node->Next();
196 }
197 delete the_list;
198 }
199
200 wxPropertyValue::~wxPropertyValue(void)
201 {
202 switch (m_type)
203 {
204 case wxPropertyValueInteger:
205 case wxPropertyValuebool:
206 case wxPropertyValueReal:
207 {
208 break;
209 }
210 case wxPropertyValueString:
211 {
212 delete[] m_value.string;
213 break;
214 }
215 case wxPropertyValueList:
216 {
217 wxPropertyValue *expr = m_value.first;
218 while (expr)
219 {
220 wxPropertyValue *expr1 = expr->m_next;
221
222 delete expr;
223 expr = expr1;
224 }
225 break;
226 }
227 default:
228 case wxPropertyValueNull: break;
229 }
230 }
231
232 void wxPropertyValue::Append(wxPropertyValue *expr)
233 {
234 m_modifiedFlag = TRUE;
235 if (!m_value.first)
236 m_value.first = expr;
237
238 if (m_last)
239 m_last->m_next = expr;
240 m_last = expr;
241 }
242
243 void wxPropertyValue::Insert(wxPropertyValue *expr)
244 {
245 m_modifiedFlag = TRUE;
246 expr->m_next = m_value.first;
247 m_value.first = expr;
248
249 if (!m_last)
250 m_last = expr;
251 }
252
253 // Delete from list
254 void wxPropertyValue::Delete(wxPropertyValue *node)
255 {
256 wxPropertyValue *expr = GetFirst();
257
258 wxPropertyValue *previous = NULL;
259 while (expr && (expr != node))
260 {
261 previous = expr;
262 expr = expr->GetNext();
263 }
264
265 if (expr)
266 {
267 if (previous)
268 previous->m_next = expr->m_next;
269
270 // If node was the first in the list,
271 // make the list point to the NEXT one.
272 if (GetFirst() == expr)
273 {
274 m_value.first = expr->m_next;
275 }
276
277 // If node was the last in the list,
278 // make the list 'last' pointer point to the PREVIOUS one.
279 if (GetLast() == expr)
280 {
281 if (previous)
282 m_last = previous;
283 else
284 m_last = NULL;
285 }
286 m_modifiedFlag = TRUE;
287 delete expr;
288 }
289
290 }
291
292 void wxPropertyValue::ClearList(void)
293 {
294 wxPropertyValue *val = GetFirst();
295 if (val)
296 m_modifiedFlag = TRUE;
297
298 while (val)
299 {
300 wxPropertyValue *next = val->GetNext();
301 delete val;
302 val = next;
303 }
304 m_value.first = NULL;
305 m_last = NULL;
306 }
307
308 wxPropertyValue *wxPropertyValue::NewCopy(void) const
309 {
310 switch (m_type)
311 {
312 case wxPropertyValueInteger:
313 return new wxPropertyValue(m_value.integer);
314 case wxPropertyValuebool:
315 return new wxPropertyValue((bool) (m_value.integer != 0));
316 case wxPropertyValueReal:
317 return new wxPropertyValue(m_value.real);
318 case wxPropertyValueString:
319 return new wxPropertyValue(m_value.string);
320 case wxPropertyValueList:
321 {
322 wxPropertyValue *expr = m_value.first;
323 wxPropertyValue *new_list = new wxPropertyValue;
324 new_list->SetType(wxPropertyValueList);
325 while (expr)
326 {
327 wxPropertyValue *expr2 = expr->NewCopy();
328 new_list->Append(expr2);
329 expr = expr->m_next;
330 }
331 return new_list;
332 }
333 case wxPropertyValueIntegerPtr:
334 return new wxPropertyValue(m_value.integerPtr);
335 case wxPropertyValueRealPtr:
336 return new wxPropertyValue(m_value.realPtr);
337 case wxPropertyValueboolPtr:
338 return new wxPropertyValue(m_value.boolPtr);
339 case wxPropertyValueStringPtr:
340 return new wxPropertyValue(m_value.stringPtr);
341
342 case wxPropertyValueNull:
343 #ifdef __X__
344 cerr << "Should never get here!\n";
345 #endif
346 break;
347 }
348 return NULL;
349 }
350
351 void wxPropertyValue::Copy(wxPropertyValue& copyFrom)
352 {
353 m_type = copyFrom.Type();
354
355 switch (m_type)
356 {
357 case wxPropertyValueInteger:
358 (*this) = copyFrom.IntegerValue();
359 return ;
360
361 case wxPropertyValueReal:
362 (*this) = copyFrom.RealValue();
363 return ;
364
365 case wxPropertyValueString:
366 (*this) = wxString(copyFrom.StringValue());
367 return ;
368
369 case wxPropertyValuebool:
370 (*this) = copyFrom.BoolValue();
371 return ;
372
373 // Pointers
374 case wxPropertyValueboolPtr:
375 (*this) = copyFrom.BoolValuePtr();
376 return ;
377 case wxPropertyValueRealPtr:
378 (*this) = copyFrom.RealValuePtr();
379 return ;
380 case wxPropertyValueIntegerPtr:
381 (*this) = copyFrom.IntegerValuePtr();
382 return ;
383 case wxPropertyValueStringPtr:
384 {
385 char** s = copyFrom.StringValuePtr();
386 (*this) = s;
387 return ;
388 }
389
390 case wxPropertyValueList:
391 {
392 m_value.first = NULL;
393 m_next = NULL;
394 m_last = NULL;
395 wxPropertyValue *expr = copyFrom.m_value.first;
396 while (expr)
397 {
398 wxPropertyValue *expr2 = expr->NewCopy();
399 Append(expr2);
400 expr = expr->m_next;
401 }
402 return;
403 }
404 case wxPropertyValueNull:
405 #ifdef __X__
406 cerr << "Should never get here!\n";
407 #endif
408 break;
409 }
410 }
411
412 // Return nth argument of a clause (starting from 1)
413 wxPropertyValue *wxPropertyValue::Arg(wxPropertyValueType type, int arg) const
414 {
415 wxPropertyValue *expr = m_value.first;
416 for (int i = 1; i < arg; i++)
417 if (expr)
418 expr = expr->m_next;
419
420 if (expr && (expr->m_type == type))
421 return expr;
422 else
423 return NULL;
424 }
425
426 // Return nth argument of a list expression (starting from zero)
427 wxPropertyValue *wxPropertyValue::Nth(int arg) const
428 {
429 if (m_type != wxPropertyValueList)
430 return NULL;
431
432 wxPropertyValue *expr = m_value.first;
433 for (int i = 0; i < arg; i++)
434 if (expr)
435 expr = expr->m_next;
436 else return NULL;
437
438 if (expr)
439 return expr;
440 else
441 return NULL;
442 }
443
444 // Returns the number of elements in a list expression
445 int wxPropertyValue::Number(void) const
446 {
447 if (m_type != wxPropertyValueList)
448 return 0;
449
450 int i = 0;
451 wxPropertyValue *expr = m_value.first;
452 while (expr)
453 {
454 expr = expr->m_next;
455 i ++;
456 }
457 return i;
458 }
459
460 void wxPropertyValue::WritePropertyClause(ostream& stream) // Write this expression as a top-level clause
461 {
462 if (m_type != wxPropertyValueList)
463 return;
464
465 wxPropertyValue *node = m_value.first;
466 if (node)
467 {
468 node->WritePropertyType(stream);
469 stream << "(";
470 node = node->m_next;
471 bool first = TRUE;
472 while (node)
473 {
474 if (!first)
475 stream << " ";
476 node->WritePropertyType(stream);
477 node = node->m_next;
478 if (node) stream << ",\n";
479 first = FALSE;
480 }
481 stream << ").\n\n";
482 }
483 }
484
485 void wxPropertyValue::WritePropertyType(ostream& stream) // Write as any other subexpression
486 {
487 switch (m_type)
488 {
489 case wxPropertyValueInteger:
490 {
491 stream << m_value.integer;
492 break;
493 }
494 case wxPropertyValueIntegerPtr:
495 {
496 stream << *m_value.integerPtr;
497 break;
498 }
499 case wxPropertyValuebool:
500 {
501 if (m_value.integer)
502 stream << "True";
503 else
504 stream << "False";
505 break;
506 }
507 case wxPropertyValueboolPtr:
508 {
509 if (*m_value.integerPtr)
510 stream << "True";
511 else
512 stream << "False";
513 break;
514 }
515 case wxPropertyValueReal:
516 {
517 float f = m_value.real;
518 sprintf(wxBuffer, "%.6g", (double)f);
519 stream << wxBuffer;
520 break;
521 }
522 case wxPropertyValueRealPtr:
523 {
524 float f = *m_value.realPtr;
525 /* Now the parser can cope with this.
526 // Prevent printing in 'e' notation. Any better way?
527 if (fabs(f) < 0.00001)
528 f = 0.0;
529 */
530 sprintf(wxBuffer, "%.6g", f);
531 stream << wxBuffer;
532 break;
533 }
534 case wxPropertyValueString:
535 {
536 // stream << "\"";
537 int i;
538 int len = strlen(m_value.string);
539 for (i = 0; i < len; i++)
540 {
541 char ch = m_value.string[i];
542 // if (ch == '"' || ch == '\\')
543 // stream << "\\";
544 stream << ch;
545 }
546
547 // stream << "\"";
548 break;
549 }
550 case wxPropertyValueStringPtr:
551 {
552 wxFAIL_MSG( "wxPropertyValue::WritePropertyType( wxPropertyValueStringPtr ) not implemented" );
553 /*
554 int i;
555 int len = strlen(*(m_value.stringPtr));
556 for (i = 0; i < len; i++)
557 {
558 char ch = *(m_value.stringPtr)[i];
559
560 }
561 */
562 break;
563 }
564 case wxPropertyValueList:
565 {
566 if (!m_value.first)
567 stream << "[]";
568 else
569 {
570 wxPropertyValue *expr = m_value.first;
571
572 stream << "[";
573 while (expr)
574 {
575 expr->WritePropertyType(stream);
576 expr = expr->m_next;
577 if (expr) stream << ", ";
578 }
579 stream << "]";
580 }
581 break;
582 }
583 case wxPropertyValueNull: break;
584 }
585 }
586
587 wxString wxPropertyValue::GetStringRepresentation(void)
588 {
589 char buf[500];
590 buf[0] = 0;
591
592 ostrstream str((char *)buf, (int)500, ios::out);
593 WritePropertyType(str);
594 str << '\0';
595 str.flush();
596
597 wxString theString(buf);
598 return theString;
599 }
600
601 void wxPropertyValue::operator=(const wxPropertyValue& val)
602 {
603 m_modifiedFlag = TRUE;
604 Copy((wxPropertyValue&)val);
605 }
606
607 // void wxPropertyValue::operator=(const char *val)
608 void wxPropertyValue::operator=(const wxString& val1)
609 {
610 const char *val = (const char *)val1;
611
612 m_modifiedFlag = TRUE;
613 if (m_type == wxPropertyValueNull)
614 m_type = wxPropertyValueString;
615
616 if (m_type == wxPropertyValueString)
617 {
618 if (val)
619 m_value.string = copystring(val);
620 else
621 m_value.string = NULL;
622 }
623 else if (m_type == wxPropertyValueStringPtr)
624 {
625 if (*m_value.stringPtr)
626 delete[] *m_value.stringPtr;
627 if (val)
628 *m_value.stringPtr = copystring(val);
629 else
630 *m_value.stringPtr = NULL;
631 }
632
633 m_clientData = NULL;
634 m_next = NULL;
635 m_last = NULL;
636
637 }
638
639 void wxPropertyValue::operator=(const long val)
640 {
641 m_modifiedFlag = TRUE;
642 if (m_type == wxPropertyValueNull)
643 m_type = wxPropertyValueInteger;
644
645 if (m_type == wxPropertyValueInteger)
646 m_value.integer = val;
647 else if (m_type == wxPropertyValueIntegerPtr)
648 *m_value.integerPtr = val;
649 else if (m_type == wxPropertyValueReal)
650 m_value.real = (float)val;
651 else if (m_type == wxPropertyValueRealPtr)
652 *m_value.realPtr = (float)val;
653
654 m_clientData = NULL;
655 m_next = NULL;
656 }
657
658 void wxPropertyValue::operator=(const bool val)
659 {
660 m_modifiedFlag = TRUE;
661 if (m_type == wxPropertyValueNull)
662 m_type = wxPropertyValuebool;
663
664 if (m_type == wxPropertyValuebool)
665 m_value.integer = (long)val;
666 else if (m_type == wxPropertyValueboolPtr)
667 *m_value.boolPtr = val;
668
669 m_clientData = NULL;
670 m_next = NULL;
671 }
672
673 void wxPropertyValue::operator=(const float val)
674 {
675 m_modifiedFlag = TRUE;
676 if (m_type == wxPropertyValueNull)
677 m_type = wxPropertyValueReal;
678
679 if (m_type == wxPropertyValueInteger)
680 m_value.integer = (long)val;
681 else if (m_type == wxPropertyValueIntegerPtr)
682 *m_value.integerPtr = (long)val;
683 else if (m_type == wxPropertyValueReal)
684 m_value.real = val;
685 else if (m_type == wxPropertyValueRealPtr)
686 *m_value.realPtr = val;
687
688 m_clientData = NULL;
689 m_next = NULL;
690 }
691
692 void wxPropertyValue::operator=(const char **val)
693 {
694 m_modifiedFlag = TRUE;
695 m_type = wxPropertyValueStringPtr;
696
697 if (val)
698 m_value.stringPtr = (char **)val;
699 else
700 m_value.stringPtr = NULL;
701 m_clientData = NULL;
702 m_next = NULL;
703 m_last = NULL;
704
705 }
706
707 void wxPropertyValue::operator=(const long *val)
708 {
709 m_modifiedFlag = TRUE;
710 m_type = wxPropertyValueIntegerPtr;
711 m_value.integerPtr = (long *)val;
712 m_clientData = NULL;
713 m_next = NULL;
714 }
715
716 void wxPropertyValue::operator=(const bool *val)
717 {
718 m_modifiedFlag = TRUE;
719 m_type = wxPropertyValueboolPtr;
720 m_value.boolPtr = (bool *)val;
721 m_clientData = NULL;
722 m_next = NULL;
723 }
724
725 void wxPropertyValue::operator=(const float *val)
726 {
727 m_modifiedFlag = TRUE;
728 m_type = wxPropertyValueRealPtr;
729 m_value.realPtr = (float *)val;
730 m_clientData = NULL;
731 m_next = NULL;
732 }
733
734 long wxPropertyValue::IntegerValue(void) const
735 {
736 if (m_type == wxPropertyValueInteger)
737 return m_value.integer;
738 else if (m_type == wxPropertyValueReal)
739 return (long)m_value.real;
740 else if (m_type == wxPropertyValueIntegerPtr)
741 return *m_value.integerPtr;
742 else if (m_type == wxPropertyValueRealPtr)
743 return (long)(*m_value.realPtr);
744 else return 0;
745 }
746
747 long *wxPropertyValue::IntegerValuePtr(void) const
748 {
749 return m_value.integerPtr;
750 }
751
752 float wxPropertyValue::RealValue(void) const {
753 if (m_type == wxPropertyValueReal)
754 return m_value.real;
755 else if (m_type == wxPropertyValueRealPtr)
756 return *m_value.realPtr;
757 else if (m_type == wxPropertyValueInteger)
758 return (float)m_value.integer;
759 else if (m_type == wxPropertyValueIntegerPtr)
760 return (float)*(m_value.integerPtr);
761 else return 0.0;
762 }
763
764 float *wxPropertyValue::RealValuePtr(void) const
765 {
766 return m_value.realPtr;
767 }
768
769 bool wxPropertyValue::BoolValue(void) const {
770 if (m_type == wxPropertyValueReal)
771 return (m_value.real != 0.0);
772 if (m_type == wxPropertyValueRealPtr)
773 return (*(m_value.realPtr) != 0.0);
774 else if (m_type == wxPropertyValueInteger)
775 return (m_value.integer != 0);
776 else if (m_type == wxPropertyValueIntegerPtr)
777 return (*(m_value.integerPtr) != 0);
778 else if (m_type == wxPropertyValuebool)
779 return (m_value.integer != 0);
780 else if (m_type == wxPropertyValueboolPtr)
781 return (*(m_value.boolPtr) != 0);
782 else return FALSE;
783 }
784
785 bool *wxPropertyValue::BoolValuePtr(void) const
786 {
787 return m_value.boolPtr;
788 }
789
790 char *wxPropertyValue::StringValue(void) const {
791 if (m_type == wxPropertyValueString)
792 return m_value.string;
793 else if (m_type == wxPropertyValueStringPtr)
794 return *(m_value.stringPtr);
795 else return NULL;
796 }
797
798 char **wxPropertyValue::StringValuePtr(void) const
799 {
800 return m_value.stringPtr;
801 }
802
803 /*
804 * A property (name plus value)
805 */
806
807 IMPLEMENT_DYNAMIC_CLASS(wxProperty, wxObject)
808
809 wxProperty::wxProperty(void)
810 {
811 m_propertyRole = wxEmptyString;
812 m_propertyValidator = NULL;
813 m_propertyWindow = NULL;
814 m_enabled = TRUE;
815 }
816
817 wxProperty::wxProperty(wxProperty& copyFrom)
818 {
819 m_value = copyFrom.GetValue();
820 m_name = copyFrom.GetName();
821 m_propertyRole = copyFrom.GetRole();
822 m_propertyValidator = copyFrom.GetValidator();
823 m_enabled = copyFrom.IsEnabled();
824 m_propertyWindow = NULL;
825 }
826
827 wxProperty::wxProperty(wxString nm, wxString role, wxPropertyValidator *ed):m_name(nm), m_propertyRole(role)
828 {
829 m_propertyValidator = ed;
830 m_propertyWindow = NULL;
831 m_enabled = TRUE;
832 }
833
834 wxProperty::wxProperty(wxString nm, const wxPropertyValue& val, wxString role, wxPropertyValidator *ed):
835 m_value(val), m_name(nm), m_propertyRole(role)
836 {
837 m_propertyValidator = ed;
838 m_propertyWindow = NULL;
839 m_enabled = TRUE;
840 }
841
842 wxProperty::~wxProperty(void)
843 {
844 if (m_propertyValidator)
845 delete m_propertyValidator;
846 }
847
848 wxPropertyValue& wxProperty::GetValue(void) const
849 {
850 return (wxPropertyValue&) m_value;
851 }
852
853 wxPropertyValidator *wxProperty::GetValidator(void) const
854 {
855 return m_propertyValidator;
856 }
857
858 wxString& wxProperty::GetName(void) const
859 {
860 return (wxString&) m_name;
861 }
862
863 wxString& wxProperty::GetRole(void) const
864 {
865 return (wxString&) m_propertyRole;
866 }
867
868 void wxProperty::SetValue(const wxPropertyValue& val)
869 {
870 m_value = val;
871 }
872
873 void wxProperty::SetValidator(wxPropertyValidator *ed)
874 {
875 m_propertyValidator = ed;
876 }
877
878 void wxProperty::SetRole(wxString& role)
879 {
880 m_propertyRole = role;
881 }
882
883 void wxProperty::SetName(wxString& nm)
884 {
885 m_name = nm;
886 }
887
888 void wxProperty::operator=(const wxPropertyValue& val)
889 {
890 m_value = val;
891 }
892
893 /*
894 * Base property view class
895 */
896
897 IMPLEMENT_DYNAMIC_CLASS(wxPropertyView, wxEvtHandler)
898
899 wxPropertyView::wxPropertyView(long flags)
900 {
901 m_buttonFlags = flags;
902 m_propertySheet = NULL;
903 m_currentValidator = NULL;
904 m_currentProperty = NULL;
905 }
906
907 wxPropertyView::~wxPropertyView(void)
908 {
909 }
910
911 void wxPropertyView::AddRegistry(wxPropertyValidatorRegistry *registry)
912 {
913 m_validatorRegistryList.Append(registry);
914 }
915
916 wxPropertyValidator *wxPropertyView::FindPropertyValidator(wxProperty *property)
917 {
918 if (property->GetValidator())
919 return property->GetValidator();
920
921 wxNode *node = m_validatorRegistryList.First();
922 while (node)
923 {
924 wxPropertyValidatorRegistry *registry = (wxPropertyValidatorRegistry *)node->Data();
925 wxPropertyValidator *validator = registry->GetValidator(property->GetRole());
926 if (validator)
927 return validator;
928 node = node->Next();
929 }
930 return NULL;
931 /*
932 if (!wxDefaultPropertyValidator)
933 wxDefaultPropertyValidator = new wxPropertyListValidator;
934 return wxDefaultPropertyValidator;
935 */
936 }
937
938 /*
939 * Property sheet
940 */
941
942 IMPLEMENT_DYNAMIC_CLASS(wxPropertySheet, wxObject)
943
944 wxPropertySheet::wxPropertySheet(const wxString& name)
945 :m_properties(wxKEY_STRING),m_name(name)
946 {
947 }
948
949 wxPropertySheet::~wxPropertySheet(void)
950 {
951 Clear();
952 }
953
954 bool wxPropertySheet::Save( ostream& WXUNUSED(str) )
955 {
956 return FALSE;
957 }
958
959 bool wxPropertySheet::Load( ostream& WXUNUSED(str) )
960 {
961 return FALSE;
962 }
963
964 void wxPropertySheet::UpdateAllViews( wxPropertyView *WXUNUSED(thisView) )
965 {
966 }
967
968 // Add a property
969 void wxPropertySheet::AddProperty(wxProperty *property)
970 {
971 m_properties.Append((const char*) property->GetName(), property);
972 }
973
974 // Get property by name
975 wxProperty *wxPropertySheet::GetProperty(const wxString& name) const
976 {
977 wxNode *node = m_properties.Find((const char*) name);
978 if (!node)
979 return NULL;
980 else
981 return (wxProperty *)node->Data();
982 }
983
984 bool wxPropertySheet::SetProperty(const wxString& name, const wxPropertyValue& value)
985 {
986 wxProperty* prop = GetProperty(name);
987 if(prop){
988 prop->SetValue(value);
989 return TRUE;
990 }else{
991 return FALSE;
992 }
993 }
994
995 void wxPropertySheet::RemoveProperty(const wxString& name)
996 {
997 wxNode *node = m_properties.Find(name);
998 if(node)
999 {
1000 wxProperty *prop = (wxProperty *)node->Data();
1001 delete prop;
1002 m_properties.DeleteNode(node);
1003 }
1004 }
1005
1006 bool wxPropertySheet::HasProperty(const wxString& name) const
1007 {
1008 return (GetProperty(name)?TRUE:FALSE);
1009 }
1010
1011 // Clear all properties
1012 void wxPropertySheet::Clear(void)
1013 {
1014 wxNode *node = m_properties.First();
1015 while (node)
1016 {
1017 wxProperty *prop = (wxProperty *)node->Data();
1018 wxNode *next = node->Next();
1019 delete prop;
1020 delete node;
1021 node = next;
1022 }
1023 }
1024
1025 // Sets/clears the modified flag for each property value
1026 void wxPropertySheet::SetAllModified(bool flag)
1027 {
1028 wxNode *node = m_properties.First();
1029 while (node)
1030 {
1031 wxProperty *prop = (wxProperty *)node->Data();
1032 prop->GetValue().SetModified(flag);
1033 node = node->Next();
1034 }
1035 }
1036
1037 /*
1038 * Property validator registry
1039 *
1040 */
1041
1042 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValidatorRegistry, wxHashTable)
1043
1044 wxPropertyValidatorRegistry::wxPropertyValidatorRegistry(void):wxHashTable(wxKEY_STRING)
1045 {
1046 }
1047
1048 wxPropertyValidatorRegistry::~wxPropertyValidatorRegistry(void)
1049 {
1050 ClearRegistry();
1051 }
1052
1053 void wxPropertyValidatorRegistry::RegisterValidator(const wxString& typeName, wxPropertyValidator *validator)
1054 {
1055 Put((const char*) typeName, validator);
1056 }
1057
1058 wxPropertyValidator *wxPropertyValidatorRegistry::GetValidator(const wxString& typeName)
1059 {
1060 return (wxPropertyValidator *)Get((const char*) typeName);
1061 }
1062
1063 void wxPropertyValidatorRegistry::ClearRegistry(void)
1064 {
1065 BeginFind();
1066 wxNode *node;
1067 while ((node = Next()))
1068 {
1069 delete (wxPropertyValidator *)node->Data();
1070 }
1071 }
1072
1073 /*
1074 * Property validator
1075 */
1076
1077
1078 IMPLEMENT_ABSTRACT_CLASS(wxPropertyValidator, wxEvtHandler)
1079
1080 wxPropertyValidator::wxPropertyValidator(long flags)
1081 {
1082 m_validatorFlags = flags;
1083 m_validatorProperty = NULL;
1084 }
1085
1086 wxPropertyValidator::~wxPropertyValidator(void)
1087 {}
1088
1089 bool wxPropertyValidator::StringToFloat (char *s, float *number) {
1090 double num;
1091 bool ok = StringToDouble (s, &num);
1092 *number = (float) num;
1093 return ok;
1094 }
1095
1096 bool wxPropertyValidator::StringToDouble (char *s, double *number) {
1097 bool ok = TRUE;
1098 char *value_ptr;
1099 *number = strtod (s, &value_ptr);
1100 if (value_ptr) {
1101 int len = strlen (value_ptr);
1102 for (int i = 0; i < len; i++) {
1103 ok = (isspace (value_ptr[i]) != 0);
1104 if (!ok) return FALSE;
1105 }
1106 }
1107 return ok;
1108 }
1109
1110 bool wxPropertyValidator::StringToInt (char *s, int *number) {
1111 long num;
1112 bool ok = StringToLong (s, &num);
1113 *number = (int) num;
1114 return ok;
1115 }
1116
1117 bool wxPropertyValidator::StringToLong (char *s, long *number) {
1118 bool ok = TRUE;
1119 char *value_ptr;
1120 *number = strtol (s, &value_ptr, 10);
1121 if (value_ptr) {
1122 int len = strlen (value_ptr);
1123 for (int i = 0; i < len; i++) {
1124 ok = (isspace (value_ptr[i]) != 0);
1125 if (!ok) return FALSE;
1126 }
1127 }
1128 return ok;
1129 }
1130
1131 char *wxPropertyValidator::FloatToString (float number) {
1132 static char buf[20];
1133 sprintf (buf, "%.6g", number);
1134 return buf;
1135 }
1136
1137 char *wxPropertyValidator::DoubleToString (double number) {
1138 static char buf[20];
1139 sprintf (buf, "%.6g", number);
1140 return buf;
1141 }
1142
1143 char *wxPropertyValidator::IntToString (int number) {
1144 return ::IntToString (number);
1145 }
1146
1147 char *wxPropertyValidator::LongToString (long number) {
1148 return ::LongToString (number);
1149 }
1150
1151