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(__WXMSW__) && !defined(__GNUWIN32__)
35 #include <strstream.h>
38 #include "wx/window.h"
43 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValue
, wxObject
)
45 wxPropertyValue::wxPropertyValue(void)
47 m_type
= wxPropertyValueNull
;
52 m_modifiedFlag
= FALSE
;
55 wxPropertyValue::wxPropertyValue(const wxPropertyValue
& copyFrom
)
57 m_modifiedFlag
= FALSE
;
58 Copy((wxPropertyValue
& )copyFrom
);
61 wxPropertyValue::wxPropertyValue(const char *val
)
63 m_modifiedFlag
= FALSE
;
64 m_type
= wxPropertyValueString
;
66 m_value
.string
= copystring(val
);
72 wxPropertyValue::wxPropertyValue(const wxString
& val
)
74 m_modifiedFlag
= FALSE
;
75 m_type
= wxPropertyValueString
;
77 m_value
.string
= copystring((const char *)val
);
83 wxPropertyValue::wxPropertyValue(long the_integer
)
85 m_modifiedFlag
= FALSE
;
86 m_type
= wxPropertyValueInteger
;
87 m_value
.integer
= the_integer
;
92 wxPropertyValue::wxPropertyValue(bool val
)
94 m_modifiedFlag
= FALSE
;
95 m_type
= wxPropertyValuebool
;
96 m_value
.integer
= val
;
101 wxPropertyValue::wxPropertyValue(float the_real
)
103 m_modifiedFlag
= FALSE
;
104 m_type
= wxPropertyValueReal
;
105 m_value
.real
= the_real
;
110 wxPropertyValue::wxPropertyValue(double the_real
)
112 m_modifiedFlag
= FALSE
;
113 m_type
= wxPropertyValueReal
;
114 m_value
.real
= (float)the_real
;
119 // Pointer versions: we have a pointer to the real C++ value.
120 wxPropertyValue::wxPropertyValue(char **val
)
122 m_modifiedFlag
= FALSE
;
123 m_type
= wxPropertyValueStringPtr
;
125 m_value
.stringPtr
= val
;
131 wxPropertyValue::wxPropertyValue(long *val
)
133 m_modifiedFlag
= FALSE
;
134 m_type
= wxPropertyValueIntegerPtr
;
135 m_value
.integerPtr
= val
;
140 wxPropertyValue::wxPropertyValue(bool *val
)
142 m_modifiedFlag
= FALSE
;
143 m_type
= wxPropertyValueboolPtr
;
144 m_value
.boolPtr
= val
;
149 wxPropertyValue::wxPropertyValue(float *val
)
151 m_modifiedFlag
= FALSE
;
152 m_type
= wxPropertyValueRealPtr
;
153 m_value
.realPtr
= val
;
158 wxPropertyValue::wxPropertyValue(wxList
*the_list
)
160 m_modifiedFlag
= FALSE
;
161 m_type
= wxPropertyValueList
;
164 m_value
.first
= NULL
;
166 wxNode
*node
= the_list
->First();
169 wxPropertyValue
*expr
= (wxPropertyValue
*)node
->Data();
177 wxPropertyValue::wxPropertyValue(wxStringList
*the_list
)
179 m_modifiedFlag
= FALSE
;
180 m_type
= wxPropertyValueList
;
183 m_value
.first
= NULL
;
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
:
207 delete m_value
.string
;
210 case wxPropertyValueList
:
212 wxPropertyValue
*expr
= m_value
.first
;
215 wxPropertyValue
*expr1
= expr
->m_next
;
223 case wxPropertyValueNull
: break;
227 void wxPropertyValue::Append(wxPropertyValue
*expr
)
229 m_modifiedFlag
= TRUE
;
231 m_value
.first
= expr
;
234 m_last
->m_next
= expr
;
238 void wxPropertyValue::Insert(wxPropertyValue
*expr
)
240 m_modifiedFlag
= TRUE
;
241 expr
->m_next
= m_value
.first
;
242 m_value
.first
= expr
;
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
->m_next
= expr
->m_next
;
265 // If node was the first in the list,
266 // make the list point to the NEXT one.
267 if (GetFirst() == expr
)
269 m_value
.first
= expr
->m_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
)
281 m_modifiedFlag
= TRUE
;
287 void wxPropertyValue::ClearList(void)
289 wxPropertyValue
*val
= GetFirst();
291 m_modifiedFlag
= TRUE
;
295 wxPropertyValue
*next
= val
->GetNext();
299 m_value
.first
= NULL
;
303 wxPropertyValue
*wxPropertyValue::NewCopy(void) const
307 case wxPropertyValueInteger
:
308 return new wxPropertyValue(m_value
.integer
);
309 case wxPropertyValuebool
:
310 return new wxPropertyValue((bool) (m_value
.integer
!= 0));
311 case wxPropertyValueReal
:
312 return new wxPropertyValue(m_value
.real
);
313 case wxPropertyValueString
:
314 return new wxPropertyValue(m_value
.string
);
315 case wxPropertyValueList
:
317 wxPropertyValue
*expr
= m_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(m_value
.integerPtr
);
330 case wxPropertyValueRealPtr
:
331 return new wxPropertyValue(m_value
.realPtr
);
332 case wxPropertyValueboolPtr
:
333 return new wxPropertyValue(m_value
.boolPtr
);
334 case wxPropertyValueStringPtr
:
335 return new wxPropertyValue(m_value
.stringPtr
);
337 case wxPropertyValueNull
:
339 cerr
<< "Should never get here!\n";
346 void wxPropertyValue::Copy(wxPropertyValue
& copyFrom
)
348 m_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
:
380 char** s
= copyFrom
.StringValuePtr();
385 case wxPropertyValueList
:
387 m_value
.first
= NULL
;
390 wxPropertyValue
*expr
= copyFrom
.m_value
.first
;
393 wxPropertyValue
*expr2
= expr
->NewCopy();
399 case wxPropertyValueNull
:
401 cerr
<< "Should never get here!\n";
407 // Return nth argument of a clause (starting from 1)
408 wxPropertyValue
*wxPropertyValue::Arg(wxPropertyValueType type
, int arg
) const
410 wxPropertyValue
*expr
= m_value
.first
;
411 for (int i
= 1; i
< arg
; i
++)
415 if (expr
&& (expr
->m_type
== type
))
421 // Return nth argument of a list expression (starting from zero)
422 wxPropertyValue
*wxPropertyValue::Nth(int arg
) const
424 if (m_type
!= wxPropertyValueList
)
427 wxPropertyValue
*expr
= m_value
.first
;
428 for (int i
= 0; i
< arg
; i
++)
439 // Returns the number of elements in a list expression
440 int wxPropertyValue::Number(void) const
442 if (m_type
!= wxPropertyValueList
)
446 wxPropertyValue
*expr
= m_value
.first
;
455 void wxPropertyValue::WritePropertyClause(ostream
& stream
) // Write this expression as a top-level clause
457 if (m_type
!= wxPropertyValueList
)
460 wxPropertyValue
*node
= m_value
.first
;
463 node
->WritePropertyType(stream
);
471 node
->WritePropertyType(stream
);
473 if (node
) stream
<< ",\n";
480 void wxPropertyValue::WritePropertyType(ostream
& stream
) // Write as any other subexpression
484 case wxPropertyValueInteger
:
486 stream
<< m_value
.integer
;
489 case wxPropertyValueIntegerPtr
:
491 stream
<< *m_value
.integerPtr
;
494 case wxPropertyValuebool
:
502 case wxPropertyValueboolPtr
:
504 if (*m_value
.integerPtr
)
510 case wxPropertyValueReal
:
512 float f
= m_value
.real
;
513 sprintf(wxBuffer
, "%.6g", (double)f
);
517 case wxPropertyValueRealPtr
:
519 float f
= *m_value
.realPtr
;
520 /* Now the parser can cope with this.
521 // Prevent printing in 'e' notation. Any better way?
522 if (fabs(f) < 0.00001)
525 sprintf(wxBuffer
, "%.6g", f
);
529 case wxPropertyValueString
:
533 int len
= strlen(m_value
.string
);
534 for (i
= 0; i
< len
; i
++)
536 char ch
= m_value
.string
[i
];
537 // if (ch == '"' || ch == '\\')
545 case wxPropertyValueStringPtr
:
548 int len
= strlen(*(m_value
.stringPtr
));
549 for (i
= 0; i
< len
; i
++)
551 char ch
= *(m_value
.stringPtr
)[i
];
556 case wxPropertyValueList
:
562 wxPropertyValue
*expr
= m_value
.first
;
567 expr
->WritePropertyType(stream
);
569 if (expr
) stream
<< ", ";
575 case wxPropertyValueNull
: break;
579 wxString
wxPropertyValue::GetStringRepresentation(void)
584 ostrstream
str((char *)buf
, (int)500, ios::out
);
585 WritePropertyType(str
);
589 wxString
theString(buf
);
593 void wxPropertyValue::operator=(const wxPropertyValue
& val
)
595 m_modifiedFlag
= TRUE
;
596 Copy((wxPropertyValue
&)val
);
599 // void wxPropertyValue::operator=(const char *val)
600 void wxPropertyValue::operator=(const wxString
& val1
)
602 const char *val
= (const char *)val1
;
604 m_modifiedFlag
= TRUE
;
605 if (m_type
== wxPropertyValueNull
)
606 m_type
= wxPropertyValueString
;
608 if (m_type
== wxPropertyValueString
)
611 m_value
.string
= copystring(val
);
613 m_value
.string
= NULL
;
615 else if (m_type
== wxPropertyValueStringPtr
)
617 if (*m_value
.stringPtr
)
618 delete[] *m_value
.stringPtr
;
620 *m_value
.stringPtr
= copystring(val
);
622 *m_value
.stringPtr
= NULL
;
631 void wxPropertyValue::operator=(const long val
)
633 m_modifiedFlag
= TRUE
;
634 if (m_type
== wxPropertyValueNull
)
635 m_type
= wxPropertyValueInteger
;
637 if (m_type
== wxPropertyValueInteger
)
638 m_value
.integer
= val
;
639 else if (m_type
== wxPropertyValueIntegerPtr
)
640 *m_value
.integerPtr
= val
;
641 else if (m_type
== wxPropertyValueReal
)
642 m_value
.real
= (float)val
;
643 else if (m_type
== wxPropertyValueRealPtr
)
644 *m_value
.realPtr
= (float)val
;
650 void wxPropertyValue::operator=(const bool val
)
652 m_modifiedFlag
= TRUE
;
653 if (m_type
== wxPropertyValueNull
)
654 m_type
= wxPropertyValuebool
;
656 if (m_type
== wxPropertyValuebool
)
657 m_value
.integer
= (long)val
;
658 else if (m_type
== wxPropertyValueboolPtr
)
659 *m_value
.boolPtr
= val
;
665 void wxPropertyValue::operator=(const float val
)
667 m_modifiedFlag
= TRUE
;
668 if (m_type
== wxPropertyValueNull
)
669 m_type
= wxPropertyValueReal
;
671 if (m_type
== wxPropertyValueInteger
)
672 m_value
.integer
= (long)val
;
673 else if (m_type
== wxPropertyValueIntegerPtr
)
674 *m_value
.integerPtr
= (long)val
;
675 else if (m_type
== wxPropertyValueReal
)
677 else if (m_type
== wxPropertyValueRealPtr
)
678 *m_value
.realPtr
= val
;
684 void wxPropertyValue::operator=(const char **val
)
686 m_modifiedFlag
= TRUE
;
687 m_type
= wxPropertyValueStringPtr
;
690 m_value
.stringPtr
= (char **)val
;
692 m_value
.stringPtr
= NULL
;
699 void wxPropertyValue::operator=(const long *val
)
701 m_modifiedFlag
= TRUE
;
702 m_type
= wxPropertyValueIntegerPtr
;
703 m_value
.integerPtr
= (long *)val
;
708 void wxPropertyValue::operator=(const bool *val
)
710 m_modifiedFlag
= TRUE
;
711 m_type
= wxPropertyValueboolPtr
;
712 m_value
.boolPtr
= (bool *)val
;
717 void wxPropertyValue::operator=(const float *val
)
719 m_modifiedFlag
= TRUE
;
720 m_type
= wxPropertyValueRealPtr
;
721 m_value
.realPtr
= (float *)val
;
726 long wxPropertyValue::IntegerValue(void) const
728 if (m_type
== wxPropertyValueInteger
)
729 return m_value
.integer
;
730 else if (m_type
== wxPropertyValueReal
)
731 return (long)m_value
.real
;
732 else if (m_type
== wxPropertyValueIntegerPtr
)
733 return *m_value
.integerPtr
;
734 else if (m_type
== wxPropertyValueRealPtr
)
735 return (long)(*m_value
.realPtr
);
739 long *wxPropertyValue::IntegerValuePtr(void) const
741 return m_value
.integerPtr
;
744 float wxPropertyValue::RealValue(void) const {
745 if (m_type
== wxPropertyValueReal
)
747 else if (m_type
== wxPropertyValueRealPtr
)
748 return *m_value
.realPtr
;
749 else if (m_type
== wxPropertyValueInteger
)
750 return (float)m_value
.integer
;
751 else if (m_type
== wxPropertyValueIntegerPtr
)
752 return (float)*(m_value
.integerPtr
);
756 float *wxPropertyValue::RealValuePtr(void) const
758 return m_value
.realPtr
;
761 bool wxPropertyValue::BoolValue(void) const {
762 if (m_type
== wxPropertyValueReal
)
763 return (m_value
.real
!= 0.0);
764 if (m_type
== wxPropertyValueRealPtr
)
765 return (*(m_value
.realPtr
) != 0.0);
766 else if (m_type
== wxPropertyValueInteger
)
767 return (m_value
.integer
!= 0);
768 else if (m_type
== wxPropertyValueIntegerPtr
)
769 return (*(m_value
.integerPtr
) != 0);
770 else if (m_type
== wxPropertyValuebool
)
771 return (m_value
.integer
!= 0);
772 else if (m_type
== wxPropertyValueboolPtr
)
773 return (*(m_value
.boolPtr
) != 0);
777 bool *wxPropertyValue::BoolValuePtr(void) const
779 return m_value
.boolPtr
;
782 char *wxPropertyValue::StringValue(void) const {
783 if (m_type
== wxPropertyValueString
)
784 return m_value
.string
;
785 else if (m_type
== wxPropertyValueStringPtr
)
786 return *(m_value
.stringPtr
);
790 char **wxPropertyValue::StringValuePtr(void) const
792 return m_value
.stringPtr
;
796 * A property (name plus value)
799 IMPLEMENT_DYNAMIC_CLASS(wxProperty
, wxObject
)
801 wxProperty::wxProperty(void)
803 m_propertyRole
= (char *)NULL
;
804 m_propertyValidator
= NULL
;
805 m_propertyWindow
= NULL
;
809 wxProperty::wxProperty(wxProperty
& copyFrom
)
811 m_value
= copyFrom
.GetValue();
812 m_name
= copyFrom
.GetName();
813 m_propertyRole
= copyFrom
.GetRole();
814 m_propertyValidator
= copyFrom
.GetValidator();
815 m_enabled
= copyFrom
.IsEnabled();
816 m_propertyWindow
= NULL
;
819 wxProperty::wxProperty(wxString nm
, wxString role
, wxPropertyValidator
*ed
):m_name(nm
), m_propertyRole(role
)
821 m_propertyValidator
= ed
;
822 m_propertyWindow
= NULL
;
826 wxProperty::wxProperty(wxString nm
, const wxPropertyValue
& val
, wxString role
, wxPropertyValidator
*ed
):
827 m_name(nm
), m_value(val
), m_propertyRole(role
)
829 m_propertyValidator
= ed
;
830 m_propertyWindow
= NULL
;
834 wxProperty::~wxProperty(void)
836 if (m_propertyValidator
)
837 delete m_propertyValidator
;
840 wxPropertyValue
& wxProperty::GetValue(void) const
842 return (wxPropertyValue
&) m_value
;
845 wxPropertyValidator
*wxProperty::GetValidator(void) const
847 return m_propertyValidator
;
850 wxString
& wxProperty::GetName(void) const
852 return (wxString
&) m_name
;
855 wxString
& wxProperty::GetRole(void) const
857 return (wxString
&) m_propertyRole
;
860 void wxProperty::SetValue(const wxPropertyValue
& val
)
865 void wxProperty::SetValidator(wxPropertyValidator
*ed
)
867 m_propertyValidator
= ed
;
870 void wxProperty::SetRole(wxString
& role
)
872 m_propertyRole
= role
;
875 void wxProperty::SetName(wxString
& nm
)
880 void wxProperty::operator=(const wxPropertyValue
& val
)
886 * Base property view class
889 IMPLEMENT_DYNAMIC_CLASS(wxPropertyView
, wxEvtHandler
)
891 wxPropertyView::wxPropertyView(long flags
)
893 m_buttonFlags
= flags
;
894 m_propertySheet
= NULL
;
895 m_currentValidator
= NULL
;
896 m_currentProperty
= NULL
;
899 wxPropertyView::~wxPropertyView(void)
903 void wxPropertyView::AddRegistry(wxPropertyValidatorRegistry
*registry
)
905 m_validatorRegistryList
.Append(registry
);
908 wxPropertyValidator
*wxPropertyView::FindPropertyValidator(wxProperty
*property
)
910 if (property
->GetValidator())
911 return property
->GetValidator();
913 wxNode
*node
= m_validatorRegistryList
.First();
916 wxPropertyValidatorRegistry
*registry
= (wxPropertyValidatorRegistry
*)node
->Data();
917 wxPropertyValidator
*validator
= registry
->GetValidator(property
->GetRole());
924 if (!wxDefaultPropertyValidator)
925 wxDefaultPropertyValidator = new wxPropertyListValidator;
926 return wxDefaultPropertyValidator;
934 IMPLEMENT_DYNAMIC_CLASS(wxPropertySheet
, wxObject
)
936 wxPropertySheet::wxPropertySheet(void):m_properties(wxKEY_STRING
)
940 wxPropertySheet::~wxPropertySheet(void)
945 bool wxPropertySheet::Save( ostream
& WXUNUSED(str
) )
950 bool wxPropertySheet::Load( ostream
& WXUNUSED(str
) )
955 void wxPropertySheet::UpdateAllViews( wxPropertyView
*WXUNUSED(thisView
) )
960 void wxPropertySheet::AddProperty(wxProperty
*property
)
962 m_properties
.Append(property
->GetName().GetData(), property
);
965 // Get property by name
966 wxProperty
*wxPropertySheet::GetProperty(wxString name
)
968 wxNode
*node
= m_properties
.Find(name
.GetData());
972 return (wxProperty
*)node
->Data();
975 // Clear all properties
976 void wxPropertySheet::Clear(void)
978 wxNode
*node
= m_properties
.First();
981 wxProperty
*prop
= (wxProperty
*)node
->Data();
982 wxNode
*next
= node
->Next();
989 // Sets/clears the modified flag for each property value
990 void wxPropertySheet::SetAllModified(bool flag
)
992 wxNode
*node
= m_properties
.First();
995 wxProperty
*prop
= (wxProperty
*)node
->Data();
996 prop
->GetValue().SetModified(flag
);
1002 * Property validator registry
1006 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValidatorRegistry
, wxHashTable
)
1008 wxPropertyValidatorRegistry::wxPropertyValidatorRegistry(void):wxHashTable(wxKEY_STRING
)
1012 wxPropertyValidatorRegistry::~wxPropertyValidatorRegistry(void)
1017 void wxPropertyValidatorRegistry::RegisterValidator(wxString
& typeName
, wxPropertyValidator
*validator
)
1019 Put(typeName
.GetData(), validator
);
1022 wxPropertyValidator
*wxPropertyValidatorRegistry::GetValidator(wxString
& typeName
)
1024 return (wxPropertyValidator
*)Get(typeName
.GetData());
1027 void wxPropertyValidatorRegistry::ClearRegistry(void)
1031 while (node
= Next())
1033 delete (wxPropertyValidator
*)node
->Data();
1038 * Property validator
1042 IMPLEMENT_ABSTRACT_CLASS(wxPropertyValidator
, wxEvtHandler
)
1044 wxPropertyValidator::wxPropertyValidator(long flags
)
1046 m_validatorFlags
= flags
;
1047 m_validatorProperty
= NULL
;
1050 wxPropertyValidator::~wxPropertyValidator(void)
1053 bool wxPropertyValidator::StringToFloat (char *s
, float *number
) {
1055 bool ok
= StringToDouble (s
, &num
);
1056 *number
= (float) num
;
1060 bool wxPropertyValidator::StringToDouble (char *s
, double *number
) {
1063 *number
= strtod (s
, &value_ptr
);
1065 int len
= strlen (value_ptr
);
1066 for (int i
= 0; i
< len
; i
++) {
1067 ok
= (isspace (value_ptr
[i
]) != 0);
1068 if (!ok
) return FALSE
;
1074 bool wxPropertyValidator::StringToInt (char *s
, int *number
) {
1076 bool ok
= StringToLong (s
, &num
);
1077 *number
= (int) num
;
1081 bool wxPropertyValidator::StringToLong (char *s
, long *number
) {
1084 *number
= strtol (s
, &value_ptr
, 10);
1086 int len
= strlen (value_ptr
);
1087 for (int i
= 0; i
< len
; i
++) {
1088 ok
= (isspace (value_ptr
[i
]) != 0);
1089 if (!ok
) return FALSE
;
1095 char *wxPropertyValidator::FloatToString (float number
) {
1096 static char buf
[20];
1097 sprintf (buf
, "%.6g", number
);
1101 char *wxPropertyValidator::DoubleToString (double number
) {
1102 static char buf
[20];
1103 sprintf (buf
, "%.6g", number
);
1107 char *wxPropertyValidator::IntToString (int number
) {
1108 return ::IntToString (number
);
1111 char *wxPropertyValidator::LongToString (long number
) {
1112 return ::LongToString (number
);