1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Propert sheet classes implementation
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "prop.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
32 #if defined(__WINDOWS__) && !defined(__GNUWIN32__)
35 #include <strstream.h>
38 #include "wx/window.h"
43 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValue
, wxObject
)
45 wxPropertyValue::wxPropertyValue(void)
47 type
= wxPropertyValueNull
;
55 wxPropertyValue::wxPropertyValue(const wxPropertyValue
& copyFrom
)
58 Copy((wxPropertyValue
& )copyFrom
);
61 wxPropertyValue::wxPropertyValue(const char *val
)
64 type
= wxPropertyValueString
;
66 value
.string
= copystring(val
);
72 wxPropertyValue::wxPropertyValue(const wxString
& val
)
75 type
= wxPropertyValueString
;
77 value
.string
= copystring((const char *)val
);
83 wxPropertyValue::wxPropertyValue(long the_integer
)
86 type
= wxPropertyValueInteger
;
87 value
.integer
= the_integer
;
92 wxPropertyValue::wxPropertyValue(bool val
)
95 type
= wxPropertyValuebool
;
101 wxPropertyValue::wxPropertyValue(float the_real
)
103 modifiedFlag
= FALSE
;
104 type
= wxPropertyValueReal
;
105 value
.real
= the_real
;
110 wxPropertyValue::wxPropertyValue(double the_real
)
112 modifiedFlag
= FALSE
;
113 type
= wxPropertyValueReal
;
114 value
.real
= (float)the_real
;
119 // Pointer versions: we have a pointer to the real C++ value.
120 wxPropertyValue::wxPropertyValue(char **val
)
122 modifiedFlag
= FALSE
;
123 type
= wxPropertyValueStringPtr
;
125 value
.stringPtr
= val
;
131 wxPropertyValue::wxPropertyValue(long *val
)
133 modifiedFlag
= FALSE
;
134 type
= wxPropertyValueIntegerPtr
;
135 value
.integerPtr
= val
;
140 wxPropertyValue::wxPropertyValue(bool *val
)
142 modifiedFlag
= FALSE
;
143 type
= wxPropertyValueboolPtr
;
149 wxPropertyValue::wxPropertyValue(float *val
)
151 modifiedFlag
= FALSE
;
152 type
= wxPropertyValueRealPtr
;
158 wxPropertyValue::wxPropertyValue(wxList
*the_list
)
160 modifiedFlag
= FALSE
;
161 type
= wxPropertyValueList
;
166 wxNode
*node
= the_list
->First();
169 wxPropertyValue
*expr
= (wxPropertyValue
*)node
->Data();
177 wxPropertyValue::wxPropertyValue(wxStringList
*the_list
)
179 modifiedFlag
= FALSE
;
180 type
= wxPropertyValueList
;
185 wxNode
*node
= the_list
->First();
188 char *s
= (char *)node
->Data();
189 Append(new wxPropertyValue(s
));
195 wxPropertyValue::~wxPropertyValue(void)
199 case wxPropertyValueInteger
:
200 case wxPropertyValuebool
:
201 case wxPropertyValueReal
:
205 case wxPropertyValueString
:
210 case wxPropertyValueList
:
212 wxPropertyValue
*expr
= value
.first
;
215 wxPropertyValue
*expr1
= expr
->next
;
223 case wxPropertyValueNull
: break;
227 void wxPropertyValue::Append(wxPropertyValue
*expr
)
238 void wxPropertyValue::Insert(wxPropertyValue
*expr
)
241 expr
->next
= value
.first
;
249 void wxPropertyValue::Delete(wxPropertyValue
*node
)
251 wxPropertyValue
*expr
= GetFirst();
253 wxPropertyValue
*previous
= NULL
;
254 while (expr
&& (expr
!= node
))
257 expr
= expr
->GetNext();
263 previous
->next
= expr
->next
;
265 // If node was the first in the list,
266 // make the list point to the NEXT one.
267 if (GetFirst() == expr
)
269 value
.first
= expr
->next
;
272 // If node was the last in the list,
273 // make the list 'last' pointer point to the PREVIOUS one.
274 if (GetLast() == expr
)
287 void wxPropertyValue::ClearList(void)
289 wxPropertyValue
*val
= GetFirst();
295 wxPropertyValue
*next
= val
->GetNext();
303 wxPropertyValue
*wxPropertyValue::NewCopy(void)
307 case wxPropertyValueInteger
:
308 return new wxPropertyValue(value
.integer
);
309 case wxPropertyValuebool
:
310 return new wxPropertyValue((bool) (value
.integer
!= 0));
311 case wxPropertyValueReal
:
312 return new wxPropertyValue(value
.real
);
313 case wxPropertyValueString
:
314 return new wxPropertyValue(value
.string
);
315 case wxPropertyValueList
:
317 wxPropertyValue
*expr
= value
.first
;
318 wxPropertyValue
*new_list
= new wxPropertyValue
;
319 new_list
->SetType(wxPropertyValueList
);
322 wxPropertyValue
*expr2
= expr
->NewCopy();
323 new_list
->Append(expr2
);
328 case wxPropertyValueIntegerPtr
:
329 return new wxPropertyValue(value
.integerPtr
);
330 case wxPropertyValueRealPtr
:
331 return new wxPropertyValue(value
.realPtr
);
332 case wxPropertyValueboolPtr
:
333 return new wxPropertyValue(value
.boolPtr
);
334 case wxPropertyValueStringPtr
:
335 return new wxPropertyValue(value
.stringPtr
);
337 case wxPropertyValueNull
:
339 cerr
<< "Should never get here!\n";
346 void wxPropertyValue::Copy(wxPropertyValue
& copyFrom
)
348 type
= copyFrom
.Type();
352 case wxPropertyValueInteger
:
353 (*this) = copyFrom
.IntegerValue();
356 case wxPropertyValueReal
:
357 (*this) = copyFrom
.RealValue();
360 case wxPropertyValueString
:
361 (*this) = wxString(copyFrom
.StringValue());
364 case wxPropertyValuebool
:
365 (*this) = copyFrom
.BoolValue();
369 case wxPropertyValueboolPtr
:
370 (*this) = copyFrom
.BoolValuePtr();
372 case wxPropertyValueRealPtr
:
373 (*this) = copyFrom
.RealValuePtr();
375 case wxPropertyValueIntegerPtr
:
376 (*this) = copyFrom
.IntegerValuePtr();
378 case wxPropertyValueStringPtr
:
379 (*this) = copyFrom
.StringValuePtr();
382 case wxPropertyValueList
:
387 wxPropertyValue
*expr
= copyFrom
.value
.first
;
390 wxPropertyValue
*expr2
= expr
->NewCopy();
396 case wxPropertyValueNull
:
398 cerr
<< "Should never get here!\n";
404 // Return nth argument of a clause (starting from 1)
405 wxPropertyValue
*wxPropertyValue::Arg(wxPropertyValueType type
, int arg
)
407 wxPropertyValue
*expr
= value
.first
;
408 for (int i
= 1; i
< arg
; i
++)
412 if (expr
&& (expr
->type
== type
))
418 // Return nth argument of a list expression (starting from zero)
419 wxPropertyValue
*wxPropertyValue::Nth(int arg
)
421 if (type
!= wxPropertyValueList
)
424 wxPropertyValue
*expr
= value
.first
;
425 for (int i
= 0; i
< arg
; i
++)
436 // Returns the number of elements in a list expression
437 int wxPropertyValue::Number(void)
439 if (type
!= wxPropertyValueList
)
443 wxPropertyValue
*expr
= value
.first
;
452 void wxPropertyValue::WritePropertyClause(ostream
& stream
) // Write this expression as a top-level clause
454 if (type
!= wxPropertyValueList
)
457 wxPropertyValue
*node
= value
.first
;
460 node
->WritePropertyType(stream
);
468 node
->WritePropertyType(stream
);
470 if (node
) stream
<< ",\n";
477 void wxPropertyValue::WritePropertyType(ostream
& stream
) // Write as any other subexpression
481 case wxPropertyValueInteger
:
483 stream
<< value
.integer
;
486 case wxPropertyValueIntegerPtr
:
488 stream
<< *value
.integerPtr
;
491 case wxPropertyValuebool
:
499 case wxPropertyValueboolPtr
:
501 if (*value
.integerPtr
)
507 case wxPropertyValueReal
:
509 float f
= value
.real
;
510 sprintf(wxBuffer
, "%.6g", (double)f
);
514 case wxPropertyValueRealPtr
:
516 float f
= *value
.realPtr
;
517 /* Now the parser can cope with this.
518 // Prevent printing in 'e' notation. Any better way?
519 if (fabs(f) < 0.00001)
522 sprintf(wxBuffer
, "%.6g", f
);
526 case wxPropertyValueString
:
530 int len
= strlen(value
.string
);
531 for (i
= 0; i
< len
; i
++)
533 char ch
= value
.string
[i
];
534 // if (ch == '"' || ch == '\\')
542 case wxPropertyValueStringPtr
:
545 int len
= strlen(*(value
.stringPtr
));
546 for (i
= 0; i
< len
; i
++)
548 char ch
= *(value
.stringPtr
)[i
];
553 case wxPropertyValueList
:
559 wxPropertyValue
*expr
= value
.first
;
564 expr
->WritePropertyType(stream
);
566 if (expr
) stream
<< ", ";
572 case wxPropertyValueNull
: break;
576 wxString
wxPropertyValue::GetStringRepresentation(void)
581 ostrstream
str((char *)buf
, (int)500, ios::out
);
582 WritePropertyType(str
);
586 wxString
theString(buf
);
590 void wxPropertyValue::operator=(const wxPropertyValue
& val
)
593 Copy((wxPropertyValue
&)val
);
596 // void wxPropertyValue::operator=(const char *val)
597 void wxPropertyValue::operator=(const wxString
& val1
)
599 const char *val
= (const char *)val1
;
602 if (type
== wxPropertyValueNull
)
603 type
= wxPropertyValueString
;
605 if (type
== wxPropertyValueString
)
608 value
.string
= copystring(val
);
612 else if (type
== wxPropertyValueStringPtr
)
614 if (*value
.stringPtr
)
615 delete[] *value
.stringPtr
;
617 *value
.stringPtr
= copystring(val
);
619 *value
.stringPtr
= NULL
;
628 void wxPropertyValue::operator=(const long val
)
631 if (type
== wxPropertyValueNull
)
632 type
= wxPropertyValueInteger
;
634 if (type
== wxPropertyValueInteger
)
636 else if (type
== wxPropertyValueIntegerPtr
)
637 *value
.integerPtr
= val
;
638 else if (type
== wxPropertyValueReal
)
639 value
.real
= (float)val
;
640 else if (type
== wxPropertyValueRealPtr
)
641 *value
.realPtr
= (float)val
;
647 void wxPropertyValue::operator=(const bool val
)
650 if (type
== wxPropertyValueNull
)
651 type
= wxPropertyValuebool
;
653 if (type
== wxPropertyValuebool
)
654 value
.integer
= (long)val
;
655 else if (type
== wxPropertyValueboolPtr
)
656 *value
.boolPtr
= val
;
662 void wxPropertyValue::operator=(const float val
)
665 if (type
== wxPropertyValueNull
)
666 type
= wxPropertyValueReal
;
668 if (type
== wxPropertyValueInteger
)
669 value
.integer
= (long)val
;
670 else if (type
== wxPropertyValueIntegerPtr
)
671 *value
.integerPtr
= (long)val
;
672 else if (type
== wxPropertyValueReal
)
674 else if (type
== wxPropertyValueRealPtr
)
675 *value
.realPtr
= val
;
681 void wxPropertyValue::operator=(const char **val
)
684 type
= wxPropertyValueStringPtr
;
687 value
.stringPtr
= (char **)val
;
689 value
.stringPtr
= NULL
;
696 void wxPropertyValue::operator=(const long *val
)
699 type
= wxPropertyValueIntegerPtr
;
700 value
.integerPtr
= (long *)val
;
705 void wxPropertyValue::operator=(const bool *val
)
708 type
= wxPropertyValueboolPtr
;
709 value
.boolPtr
= (bool *)val
;
714 void wxPropertyValue::operator=(const float *val
)
717 type
= wxPropertyValueRealPtr
;
718 value
.realPtr
= (float *)val
;
723 long wxPropertyValue::IntegerValue(void)
725 if (type
== wxPropertyValueInteger
)
726 return value
.integer
;
727 else if (type
== wxPropertyValueReal
)
728 return (long)value
.real
;
729 else if (type
== wxPropertyValueIntegerPtr
)
730 return *value
.integerPtr
;
731 else if (type
== wxPropertyValueRealPtr
)
732 return (long)(*value
.realPtr
);
736 long *wxPropertyValue::IntegerValuePtr(void)
738 return value
.integerPtr
;
741 float wxPropertyValue::RealValue(void) {
742 if (type
== wxPropertyValueReal
)
744 else if (type
== wxPropertyValueRealPtr
)
745 return *value
.realPtr
;
746 else if (type
== wxPropertyValueInteger
)
747 return (float)value
.integer
;
748 else if (type
== wxPropertyValueIntegerPtr
)
749 return (float)*(value
.integerPtr
);
753 float *wxPropertyValue::RealValuePtr(void)
755 return value
.realPtr
;
758 bool wxPropertyValue::BoolValue(void) {
759 if (type
== wxPropertyValueReal
)
760 return (value
.real
!= 0.0);
761 if (type
== wxPropertyValueRealPtr
)
762 return (*(value
.realPtr
) != 0.0);
763 else if (type
== wxPropertyValueInteger
)
764 return (value
.integer
!= 0);
765 else if (type
== wxPropertyValueIntegerPtr
)
766 return (*(value
.integerPtr
) != 0);
767 else if (type
== wxPropertyValuebool
)
768 return (value
.integer
!= 0);
769 else if (type
== wxPropertyValueboolPtr
)
770 return (*(value
.boolPtr
) != 0);
774 bool *wxPropertyValue::BoolValuePtr(void)
776 return value
.boolPtr
;
779 char *wxPropertyValue::StringValue(void) {
780 if (type
== wxPropertyValueString
)
782 else if (type
== wxPropertyValueStringPtr
)
783 return *(value
.stringPtr
);
787 char **wxPropertyValue::StringValuePtr(void)
789 return value
.stringPtr
;
793 * A property (name plus value)
796 IMPLEMENT_DYNAMIC_CLASS(wxProperty
, wxObject
)
798 wxProperty::wxProperty(void)
800 propertyRole
= (char *)NULL
;
801 propertyValidator
= NULL
;
802 propertyWindow
= NULL
;
806 wxProperty::wxProperty(wxProperty
& copyFrom
)
808 value
= copyFrom
.GetValue();
809 name
= copyFrom
.GetName();
810 propertyRole
= copyFrom
.GetRole();
811 propertyValidator
= copyFrom
.GetValidator();
812 enabled
= copyFrom
.IsEnabled();
813 propertyWindow
= NULL
;
816 wxProperty::wxProperty(wxString nm
, wxString role
, wxPropertyValidator
*ed
):name(nm
), propertyRole(role
)
818 propertyValidator
= ed
;
819 propertyWindow
= NULL
;
823 wxProperty::wxProperty(wxString nm
, const wxPropertyValue
& val
, wxString role
, wxPropertyValidator
*ed
):
824 name(nm
), value(val
), propertyRole(role
)
826 propertyValidator
= ed
;
827 propertyWindow
= NULL
;
831 wxProperty::~wxProperty(void)
833 if (propertyValidator
)
834 delete propertyValidator
;
837 wxPropertyValue
& wxProperty::GetValue(void)
842 wxPropertyValidator
*wxProperty::GetValidator(void)
844 return propertyValidator
;
847 wxString
& wxProperty::GetName(void)
852 wxString
& wxProperty::GetRole(void)
857 void wxProperty::SetValue(const wxPropertyValue
& val
)
862 void wxProperty::SetValidator(wxPropertyValidator
*ed
)
864 propertyValidator
= ed
;
867 void wxProperty::SetRole(wxString
& role
)
872 void wxProperty::SetName(wxString
& nm
)
877 void wxProperty::operator=(const wxPropertyValue
& val
)
883 * Base property view class
886 IMPLEMENT_DYNAMIC_CLASS(wxPropertyView
, wxEvtHandler
)
888 wxPropertyView::wxPropertyView(long flags
)
891 propertySheet
= NULL
;
892 currentValidator
= NULL
;
893 currentProperty
= NULL
;
896 wxPropertyView::~wxPropertyView(void)
900 void wxPropertyView::AddRegistry(wxPropertyValidatorRegistry
*registry
)
902 validatorRegistryList
.Append(registry
);
905 wxPropertyValidator
*wxPropertyView::FindPropertyValidator(wxProperty
*property
)
907 if (property
->GetValidator())
908 return property
->GetValidator();
910 wxNode
*node
= validatorRegistryList
.First();
913 wxPropertyValidatorRegistry
*registry
= (wxPropertyValidatorRegistry
*)node
->Data();
914 wxPropertyValidator
*validator
= registry
->GetValidator(property
->GetRole());
921 if (!wxDefaultPropertyValidator)
922 wxDefaultPropertyValidator = new wxPropertyListValidator;
923 return wxDefaultPropertyValidator;
931 IMPLEMENT_DYNAMIC_CLASS(wxPropertySheet
, wxObject
)
933 wxPropertySheet::wxPropertySheet(void):properties(wxKEY_STRING
)
937 wxPropertySheet::~wxPropertySheet(void)
942 bool wxPropertySheet::Save(ostream
& str
)
947 bool wxPropertySheet::Load(ostream
& str
)
952 void wxPropertySheet::UpdateAllViews(wxPropertyView
*thisView
)
957 void wxPropertySheet::AddProperty(wxProperty
*property
)
959 properties
.Append(property
->GetName().GetData(), property
);
962 // Get property by name
963 wxProperty
*wxPropertySheet::GetProperty(wxString name
)
965 wxNode
*node
= properties
.Find(name
.GetData());
969 return (wxProperty
*)node
->Data();
972 // Clear all properties
973 void wxPropertySheet::Clear(void)
975 wxNode
*node
= properties
.First();
978 wxProperty
*prop
= (wxProperty
*)node
->Data();
979 wxNode
*next
= node
->Next();
986 // Sets/clears the modified flag for each property value
987 void wxPropertySheet::SetAllModified(bool flag
)
989 wxNode
*node
= properties
.First();
992 wxProperty
*prop
= (wxProperty
*)node
->Data();
993 prop
->GetValue().SetModified(flag
);
999 * Property validator registry
1003 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValidatorRegistry
, wxHashTable
)
1005 wxPropertyValidatorRegistry::wxPropertyValidatorRegistry(void):wxHashTable(wxKEY_STRING
)
1009 wxPropertyValidatorRegistry::~wxPropertyValidatorRegistry(void)
1014 void wxPropertyValidatorRegistry::RegisterValidator(wxString
& typeName
, wxPropertyValidator
*validator
)
1016 Put(typeName
.GetData(), validator
);
1019 wxPropertyValidator
*wxPropertyValidatorRegistry::GetValidator(wxString
& typeName
)
1021 return (wxPropertyValidator
*)Get(typeName
.GetData());
1024 void wxPropertyValidatorRegistry::ClearRegistry(void)
1028 while (node
= Next())
1030 delete (wxPropertyValidator
*)node
->Data();
1035 * Property validator
1039 IMPLEMENT_ABSTRACT_CLASS(wxPropertyValidator
, wxEvtHandler
)
1041 wxPropertyValidator::wxPropertyValidator(long flags
)
1043 validatorFlags
= flags
;
1044 validatorProperty
= NULL
;
1047 wxPropertyValidator::~wxPropertyValidator(void)
1050 bool wxPropertyValidator::StringToFloat (char *s
, float *number
) {
1052 bool ok
= StringToDouble (s
, &num
);
1053 *number
= (float) num
;
1057 bool wxPropertyValidator::StringToDouble (char *s
, double *number
) {
1060 *number
= strtod (s
, &value_ptr
);
1062 int len
= strlen (value_ptr
);
1063 for (int i
= 0; i
< len
; i
++) {
1064 ok
= (isspace (value_ptr
[i
]) != 0);
1065 if (!ok
) return FALSE
;
1071 bool wxPropertyValidator::StringToInt (char *s
, int *number
) {
1073 bool ok
= StringToLong (s
, &num
);
1074 *number
= (int) num
;
1078 bool wxPropertyValidator::StringToLong (char *s
, long *number
) {
1081 *number
= strtol (s
, &value_ptr
, 10);
1083 int len
= strlen (value_ptr
);
1084 for (int i
= 0; i
< len
; i
++) {
1085 ok
= (isspace (value_ptr
[i
]) != 0);
1086 if (!ok
) return FALSE
;
1092 char *wxPropertyValidator::FloatToString (float number
) {
1093 static char buf
[20];
1094 sprintf (buf
, "%.6g", number
);
1098 char *wxPropertyValidator::DoubleToString (double number
) {
1099 static char buf
[20];
1100 sprintf (buf
, "%.6g", number
);
1104 char *wxPropertyValidator::IntToString (int number
) {
1105 return ::IntToString (number
);
1108 char *wxPropertyValidator::LongToString (long number
) {
1109 return ::LongToString (number
);