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"
33 #if defined(__WXMSW__) && !defined(__GNUWIN32__)
36 #include <strstream.h>
42 #include "wx/window.h"
47 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValue
, wxObject
)
49 wxPropertyValue::wxPropertyValue(void)
51 m_type
= wxPropertyValueNull
;
56 m_modifiedFlag
= FALSE
;
59 wxPropertyValue::wxPropertyValue(const wxPropertyValue
& copyFrom
)
61 m_modifiedFlag
= FALSE
;
62 Copy((wxPropertyValue
& )copyFrom
);
65 wxPropertyValue::wxPropertyValue(const char *val
)
67 m_modifiedFlag
= FALSE
;
68 m_type
= wxPropertyValueString
;
70 m_value
.string
= copystring(val
);
76 wxPropertyValue::wxPropertyValue(const wxString
& val
)
78 m_modifiedFlag
= FALSE
;
79 m_type
= wxPropertyValueString
;
81 m_value
.string
= copystring((const char *)val
);
87 wxPropertyValue::wxPropertyValue(long the_integer
)
89 m_modifiedFlag
= FALSE
;
90 m_type
= wxPropertyValueInteger
;
91 m_value
.integer
= the_integer
;
96 wxPropertyValue::wxPropertyValue(bool val
)
98 m_modifiedFlag
= FALSE
;
99 m_type
= wxPropertyValuebool
;
100 m_value
.integer
= val
;
105 wxPropertyValue::wxPropertyValue(float the_real
)
107 m_modifiedFlag
= FALSE
;
108 m_type
= wxPropertyValueReal
;
109 m_value
.real
= the_real
;
114 wxPropertyValue::wxPropertyValue(double the_real
)
116 m_modifiedFlag
= FALSE
;
117 m_type
= wxPropertyValueReal
;
118 m_value
.real
= (float)the_real
;
123 // Pointer versions: we have a pointer to the real C++ value.
124 wxPropertyValue::wxPropertyValue(char **val
)
126 m_modifiedFlag
= FALSE
;
127 m_type
= wxPropertyValueStringPtr
;
129 m_value
.stringPtr
= val
;
135 wxPropertyValue::wxPropertyValue(long *val
)
137 m_modifiedFlag
= FALSE
;
138 m_type
= wxPropertyValueIntegerPtr
;
139 m_value
.integerPtr
= val
;
144 wxPropertyValue::wxPropertyValue(bool *val
)
146 m_modifiedFlag
= FALSE
;
147 m_type
= wxPropertyValueboolPtr
;
148 m_value
.boolPtr
= val
;
153 wxPropertyValue::wxPropertyValue(float *val
)
155 m_modifiedFlag
= FALSE
;
156 m_type
= wxPropertyValueRealPtr
;
157 m_value
.realPtr
= val
;
162 wxPropertyValue::wxPropertyValue(wxList
*the_list
)
164 m_modifiedFlag
= FALSE
;
165 m_type
= wxPropertyValueList
;
168 m_value
.first
= NULL
;
170 wxNode
*node
= the_list
->First();
173 wxPropertyValue
*expr
= (wxPropertyValue
*)node
->Data();
181 wxPropertyValue::wxPropertyValue(wxStringList
*the_list
)
183 m_modifiedFlag
= FALSE
;
184 m_type
= wxPropertyValueList
;
187 m_value
.first
= NULL
;
189 wxNode
*node
= the_list
->First();
192 char *s
= (char *)node
->Data();
193 Append(new wxPropertyValue(s
));
199 wxPropertyValue::~wxPropertyValue(void)
203 case wxPropertyValueInteger
:
204 case wxPropertyValuebool
:
205 case wxPropertyValueReal
:
209 case wxPropertyValueString
:
211 delete[] m_value
.string
;
214 case wxPropertyValueList
:
216 wxPropertyValue
*expr
= m_value
.first
;
219 wxPropertyValue
*expr1
= expr
->m_next
;
227 case wxPropertyValueNull
: break;
231 void wxPropertyValue::Append(wxPropertyValue
*expr
)
233 m_modifiedFlag
= TRUE
;
235 m_value
.first
= expr
;
238 m_last
->m_next
= expr
;
242 void wxPropertyValue::Insert(wxPropertyValue
*expr
)
244 m_modifiedFlag
= TRUE
;
245 expr
->m_next
= m_value
.first
;
246 m_value
.first
= expr
;
253 void wxPropertyValue::Delete(wxPropertyValue
*node
)
255 wxPropertyValue
*expr
= GetFirst();
257 wxPropertyValue
*previous
= NULL
;
258 while (expr
&& (expr
!= node
))
261 expr
= expr
->GetNext();
267 previous
->m_next
= expr
->m_next
;
269 // If node was the first in the list,
270 // make the list point to the NEXT one.
271 if (GetFirst() == expr
)
273 m_value
.first
= expr
->m_next
;
276 // If node was the last in the list,
277 // make the list 'last' pointer point to the PREVIOUS one.
278 if (GetLast() == expr
)
285 m_modifiedFlag
= TRUE
;
291 void wxPropertyValue::ClearList(void)
293 wxPropertyValue
*val
= GetFirst();
295 m_modifiedFlag
= TRUE
;
299 wxPropertyValue
*next
= val
->GetNext();
303 m_value
.first
= NULL
;
307 wxPropertyValue
*wxPropertyValue::NewCopy(void) const
311 case wxPropertyValueInteger
:
312 return new wxPropertyValue(m_value
.integer
);
313 case wxPropertyValuebool
:
314 return new wxPropertyValue((bool) (m_value
.integer
!= 0));
315 case wxPropertyValueReal
:
316 return new wxPropertyValue(m_value
.real
);
317 case wxPropertyValueString
:
318 return new wxPropertyValue(m_value
.string
);
319 case wxPropertyValueList
:
321 wxPropertyValue
*expr
= m_value
.first
;
322 wxPropertyValue
*new_list
= new wxPropertyValue
;
323 new_list
->SetType(wxPropertyValueList
);
326 wxPropertyValue
*expr2
= expr
->NewCopy();
327 new_list
->Append(expr2
);
332 case wxPropertyValueIntegerPtr
:
333 return new wxPropertyValue(m_value
.integerPtr
);
334 case wxPropertyValueRealPtr
:
335 return new wxPropertyValue(m_value
.realPtr
);
336 case wxPropertyValueboolPtr
:
337 return new wxPropertyValue(m_value
.boolPtr
);
338 case wxPropertyValueStringPtr
:
339 return new wxPropertyValue(m_value
.stringPtr
);
341 case wxPropertyValueNull
:
343 cerr
<< "Should never get here!\n";
350 void wxPropertyValue::Copy(wxPropertyValue
& copyFrom
)
352 m_type
= copyFrom
.Type();
356 case wxPropertyValueInteger
:
357 (*this) = copyFrom
.IntegerValue();
360 case wxPropertyValueReal
:
361 (*this) = copyFrom
.RealValue();
364 case wxPropertyValueString
:
365 (*this) = wxString(copyFrom
.StringValue());
368 case wxPropertyValuebool
:
369 (*this) = copyFrom
.BoolValue();
373 case wxPropertyValueboolPtr
:
374 (*this) = copyFrom
.BoolValuePtr();
376 case wxPropertyValueRealPtr
:
377 (*this) = copyFrom
.RealValuePtr();
379 case wxPropertyValueIntegerPtr
:
380 (*this) = copyFrom
.IntegerValuePtr();
382 case wxPropertyValueStringPtr
:
384 char** s
= copyFrom
.StringValuePtr();
389 case wxPropertyValueList
:
391 m_value
.first
= NULL
;
394 wxPropertyValue
*expr
= copyFrom
.m_value
.first
;
397 wxPropertyValue
*expr2
= expr
->NewCopy();
403 case wxPropertyValueNull
:
405 cerr
<< "Should never get here!\n";
411 // Return nth argument of a clause (starting from 1)
412 wxPropertyValue
*wxPropertyValue::Arg(wxPropertyValueType type
, int arg
) const
414 wxPropertyValue
*expr
= m_value
.first
;
415 for (int i
= 1; i
< arg
; i
++)
419 if (expr
&& (expr
->m_type
== type
))
425 // Return nth argument of a list expression (starting from zero)
426 wxPropertyValue
*wxPropertyValue::Nth(int arg
) const
428 if (m_type
!= wxPropertyValueList
)
431 wxPropertyValue
*expr
= m_value
.first
;
432 for (int i
= 0; i
< arg
; i
++)
443 // Returns the number of elements in a list expression
444 int wxPropertyValue::Number(void) const
446 if (m_type
!= wxPropertyValueList
)
450 wxPropertyValue
*expr
= m_value
.first
;
459 void wxPropertyValue::WritePropertyClause(ostream
& stream
) // Write this expression as a top-level clause
461 if (m_type
!= wxPropertyValueList
)
464 wxPropertyValue
*node
= m_value
.first
;
467 node
->WritePropertyType(stream
);
475 node
->WritePropertyType(stream
);
477 if (node
) stream
<< ",\n";
484 void wxPropertyValue::WritePropertyType(ostream
& stream
) // Write as any other subexpression
488 case wxPropertyValueInteger
:
490 stream
<< m_value
.integer
;
493 case wxPropertyValueIntegerPtr
:
495 stream
<< *m_value
.integerPtr
;
498 case wxPropertyValuebool
:
506 case wxPropertyValueboolPtr
:
508 if (*m_value
.integerPtr
)
514 case wxPropertyValueReal
:
516 float f
= m_value
.real
;
517 sprintf(wxBuffer
, "%.6g", (double)f
);
521 case wxPropertyValueRealPtr
:
523 float f
= *m_value
.realPtr
;
524 /* Now the parser can cope with this.
525 // Prevent printing in 'e' notation. Any better way?
526 if (fabs(f) < 0.00001)
529 sprintf(wxBuffer
, "%.6g", f
);
533 case wxPropertyValueString
:
537 int len
= strlen(m_value
.string
);
538 for (i
= 0; i
< len
; i
++)
540 char ch
= m_value
.string
[i
];
541 // if (ch == '"' || ch == '\\')
549 case wxPropertyValueStringPtr
:
552 int len
= strlen(*(m_value
.stringPtr
));
553 for (i
= 0; i
< len
; i
++)
555 char ch
= *(m_value
.stringPtr
)[i
];
560 case wxPropertyValueList
:
566 wxPropertyValue
*expr
= m_value
.first
;
571 expr
->WritePropertyType(stream
);
573 if (expr
) stream
<< ", ";
579 case wxPropertyValueNull
: break;
583 wxString
wxPropertyValue::GetStringRepresentation(void)
588 ostrstream
str((char *)buf
, (int)500, ios::out
);
589 WritePropertyType(str
);
593 wxString
theString(buf
);
597 void wxPropertyValue::operator=(const wxPropertyValue
& val
)
599 m_modifiedFlag
= TRUE
;
600 Copy((wxPropertyValue
&)val
);
603 // void wxPropertyValue::operator=(const char *val)
604 void wxPropertyValue::operator=(const wxString
& val1
)
606 const char *val
= (const char *)val1
;
608 m_modifiedFlag
= TRUE
;
609 if (m_type
== wxPropertyValueNull
)
610 m_type
= wxPropertyValueString
;
612 if (m_type
== wxPropertyValueString
)
615 m_value
.string
= copystring(val
);
617 m_value
.string
= NULL
;
619 else if (m_type
== wxPropertyValueStringPtr
)
621 if (*m_value
.stringPtr
)
622 delete[] *m_value
.stringPtr
;
624 *m_value
.stringPtr
= copystring(val
);
626 *m_value
.stringPtr
= NULL
;
635 void wxPropertyValue::operator=(const long val
)
637 m_modifiedFlag
= TRUE
;
638 if (m_type
== wxPropertyValueNull
)
639 m_type
= wxPropertyValueInteger
;
641 if (m_type
== wxPropertyValueInteger
)
642 m_value
.integer
= val
;
643 else if (m_type
== wxPropertyValueIntegerPtr
)
644 *m_value
.integerPtr
= val
;
645 else if (m_type
== wxPropertyValueReal
)
646 m_value
.real
= (float)val
;
647 else if (m_type
== wxPropertyValueRealPtr
)
648 *m_value
.realPtr
= (float)val
;
654 void wxPropertyValue::operator=(const bool val
)
656 m_modifiedFlag
= TRUE
;
657 if (m_type
== wxPropertyValueNull
)
658 m_type
= wxPropertyValuebool
;
660 if (m_type
== wxPropertyValuebool
)
661 m_value
.integer
= (long)val
;
662 else if (m_type
== wxPropertyValueboolPtr
)
663 *m_value
.boolPtr
= val
;
669 void wxPropertyValue::operator=(const float val
)
671 m_modifiedFlag
= TRUE
;
672 if (m_type
== wxPropertyValueNull
)
673 m_type
= wxPropertyValueReal
;
675 if (m_type
== wxPropertyValueInteger
)
676 m_value
.integer
= (long)val
;
677 else if (m_type
== wxPropertyValueIntegerPtr
)
678 *m_value
.integerPtr
= (long)val
;
679 else if (m_type
== wxPropertyValueReal
)
681 else if (m_type
== wxPropertyValueRealPtr
)
682 *m_value
.realPtr
= val
;
688 void wxPropertyValue::operator=(const char **val
)
690 m_modifiedFlag
= TRUE
;
691 m_type
= wxPropertyValueStringPtr
;
694 m_value
.stringPtr
= (char **)val
;
696 m_value
.stringPtr
= NULL
;
703 void wxPropertyValue::operator=(const long *val
)
705 m_modifiedFlag
= TRUE
;
706 m_type
= wxPropertyValueIntegerPtr
;
707 m_value
.integerPtr
= (long *)val
;
712 void wxPropertyValue::operator=(const bool *val
)
714 m_modifiedFlag
= TRUE
;
715 m_type
= wxPropertyValueboolPtr
;
716 m_value
.boolPtr
= (bool *)val
;
721 void wxPropertyValue::operator=(const float *val
)
723 m_modifiedFlag
= TRUE
;
724 m_type
= wxPropertyValueRealPtr
;
725 m_value
.realPtr
= (float *)val
;
730 long wxPropertyValue::IntegerValue(void) const
732 if (m_type
== wxPropertyValueInteger
)
733 return m_value
.integer
;
734 else if (m_type
== wxPropertyValueReal
)
735 return (long)m_value
.real
;
736 else if (m_type
== wxPropertyValueIntegerPtr
)
737 return *m_value
.integerPtr
;
738 else if (m_type
== wxPropertyValueRealPtr
)
739 return (long)(*m_value
.realPtr
);
743 long *wxPropertyValue::IntegerValuePtr(void) const
745 return m_value
.integerPtr
;
748 float wxPropertyValue::RealValue(void) const {
749 if (m_type
== wxPropertyValueReal
)
751 else if (m_type
== wxPropertyValueRealPtr
)
752 return *m_value
.realPtr
;
753 else if (m_type
== wxPropertyValueInteger
)
754 return (float)m_value
.integer
;
755 else if (m_type
== wxPropertyValueIntegerPtr
)
756 return (float)*(m_value
.integerPtr
);
760 float *wxPropertyValue::RealValuePtr(void) const
762 return m_value
.realPtr
;
765 bool wxPropertyValue::BoolValue(void) const {
766 if (m_type
== wxPropertyValueReal
)
767 return (m_value
.real
!= 0.0);
768 if (m_type
== wxPropertyValueRealPtr
)
769 return (*(m_value
.realPtr
) != 0.0);
770 else if (m_type
== wxPropertyValueInteger
)
771 return (m_value
.integer
!= 0);
772 else if (m_type
== wxPropertyValueIntegerPtr
)
773 return (*(m_value
.integerPtr
) != 0);
774 else if (m_type
== wxPropertyValuebool
)
775 return (m_value
.integer
!= 0);
776 else if (m_type
== wxPropertyValueboolPtr
)
777 return (*(m_value
.boolPtr
) != 0);
781 bool *wxPropertyValue::BoolValuePtr(void) const
783 return m_value
.boolPtr
;
786 char *wxPropertyValue::StringValue(void) const {
787 if (m_type
== wxPropertyValueString
)
788 return m_value
.string
;
789 else if (m_type
== wxPropertyValueStringPtr
)
790 return *(m_value
.stringPtr
);
794 char **wxPropertyValue::StringValuePtr(void) const
796 return m_value
.stringPtr
;
800 * A property (name plus value)
803 IMPLEMENT_DYNAMIC_CLASS(wxProperty
, wxObject
)
805 wxProperty::wxProperty(void)
807 m_propertyRole
= (char *)NULL
;
808 m_propertyValidator
= NULL
;
809 m_propertyWindow
= NULL
;
813 wxProperty::wxProperty(wxProperty
& copyFrom
)
815 m_value
= copyFrom
.GetValue();
816 m_name
= copyFrom
.GetName();
817 m_propertyRole
= copyFrom
.GetRole();
818 m_propertyValidator
= copyFrom
.GetValidator();
819 m_enabled
= copyFrom
.IsEnabled();
820 m_propertyWindow
= NULL
;
823 wxProperty::wxProperty(wxString nm
, wxString role
, wxPropertyValidator
*ed
):m_name(nm
), m_propertyRole(role
)
825 m_propertyValidator
= ed
;
826 m_propertyWindow
= NULL
;
830 wxProperty::wxProperty(wxString nm
, const wxPropertyValue
& val
, wxString role
, wxPropertyValidator
*ed
):
831 m_name(nm
), m_value(val
), m_propertyRole(role
)
833 m_propertyValidator
= ed
;
834 m_propertyWindow
= NULL
;
838 wxProperty::~wxProperty(void)
840 if (m_propertyValidator
)
841 delete m_propertyValidator
;
844 wxPropertyValue
& wxProperty::GetValue(void) const
846 return (wxPropertyValue
&) m_value
;
849 wxPropertyValidator
*wxProperty::GetValidator(void) const
851 return m_propertyValidator
;
854 wxString
& wxProperty::GetName(void) const
856 return (wxString
&) m_name
;
859 wxString
& wxProperty::GetRole(void) const
861 return (wxString
&) m_propertyRole
;
864 void wxProperty::SetValue(const wxPropertyValue
& val
)
869 void wxProperty::SetValidator(wxPropertyValidator
*ed
)
871 m_propertyValidator
= ed
;
874 void wxProperty::SetRole(wxString
& role
)
876 m_propertyRole
= role
;
879 void wxProperty::SetName(wxString
& nm
)
884 void wxProperty::operator=(const wxPropertyValue
& val
)
890 * Base property view class
893 IMPLEMENT_DYNAMIC_CLASS(wxPropertyView
, wxEvtHandler
)
895 wxPropertyView::wxPropertyView(long flags
)
897 m_buttonFlags
= flags
;
898 m_propertySheet
= NULL
;
899 m_currentValidator
= NULL
;
900 m_currentProperty
= NULL
;
903 wxPropertyView::~wxPropertyView(void)
907 void wxPropertyView::AddRegistry(wxPropertyValidatorRegistry
*registry
)
909 m_validatorRegistryList
.Append(registry
);
912 wxPropertyValidator
*wxPropertyView::FindPropertyValidator(wxProperty
*property
)
914 if (property
->GetValidator())
915 return property
->GetValidator();
917 wxNode
*node
= m_validatorRegistryList
.First();
920 wxPropertyValidatorRegistry
*registry
= (wxPropertyValidatorRegistry
*)node
->Data();
921 wxPropertyValidator
*validator
= registry
->GetValidator(property
->GetRole());
928 if (!wxDefaultPropertyValidator)
929 wxDefaultPropertyValidator = new wxPropertyListValidator;
930 return wxDefaultPropertyValidator;
938 IMPLEMENT_DYNAMIC_CLASS(wxPropertySheet
, wxObject
)
940 wxPropertySheet::wxPropertySheet(void):m_properties(wxKEY_STRING
)
944 wxPropertySheet::~wxPropertySheet(void)
949 bool wxPropertySheet::Save( ostream
& WXUNUSED(str
) )
954 bool wxPropertySheet::Load( ostream
& WXUNUSED(str
) )
959 void wxPropertySheet::UpdateAllViews( wxPropertyView
*WXUNUSED(thisView
) )
964 void wxPropertySheet::AddProperty(wxProperty
*property
)
966 m_properties
.Append((const char*) property
->GetName(), property
);
969 // Get property by name
970 wxProperty
*wxPropertySheet::GetProperty(wxString name
)
972 wxNode
*node
= m_properties
.Find((const char*) name
);
976 return (wxProperty
*)node
->Data();
979 // Clear all properties
980 void wxPropertySheet::Clear(void)
982 wxNode
*node
= m_properties
.First();
985 wxProperty
*prop
= (wxProperty
*)node
->Data();
986 wxNode
*next
= node
->Next();
993 // Sets/clears the modified flag for each property value
994 void wxPropertySheet::SetAllModified(bool flag
)
996 wxNode
*node
= m_properties
.First();
999 wxProperty
*prop
= (wxProperty
*)node
->Data();
1000 prop
->GetValue().SetModified(flag
);
1001 node
= node
->Next();
1006 * Property validator registry
1010 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValidatorRegistry
, wxHashTable
)
1012 wxPropertyValidatorRegistry::wxPropertyValidatorRegistry(void):wxHashTable(wxKEY_STRING
)
1016 wxPropertyValidatorRegistry::~wxPropertyValidatorRegistry(void)
1021 void wxPropertyValidatorRegistry::RegisterValidator(const wxString
& typeName
, wxPropertyValidator
*validator
)
1023 Put((const char*) typeName
, validator
);
1026 wxPropertyValidator
*wxPropertyValidatorRegistry::GetValidator(const wxString
& typeName
)
1028 return (wxPropertyValidator
*)Get((const char*) typeName
);
1031 void wxPropertyValidatorRegistry::ClearRegistry(void)
1035 while (node
= Next())
1037 delete (wxPropertyValidator
*)node
->Data();
1042 * Property validator
1046 IMPLEMENT_ABSTRACT_CLASS(wxPropertyValidator
, wxEvtHandler
)
1048 wxPropertyValidator::wxPropertyValidator(long flags
)
1050 m_validatorFlags
= flags
;
1051 m_validatorProperty
= NULL
;
1054 wxPropertyValidator::~wxPropertyValidator(void)
1057 bool wxPropertyValidator::StringToFloat (char *s
, float *number
) {
1059 bool ok
= StringToDouble (s
, &num
);
1060 *number
= (float) num
;
1064 bool wxPropertyValidator::StringToDouble (char *s
, double *number
) {
1067 *number
= strtod (s
, &value_ptr
);
1069 int len
= strlen (value_ptr
);
1070 for (int i
= 0; i
< len
; i
++) {
1071 ok
= (isspace (value_ptr
[i
]) != 0);
1072 if (!ok
) return FALSE
;
1078 bool wxPropertyValidator::StringToInt (char *s
, int *number
) {
1080 bool ok
= StringToLong (s
, &num
);
1081 *number
= (int) num
;
1085 bool wxPropertyValidator::StringToLong (char *s
, long *number
) {
1088 *number
= strtol (s
, &value_ptr
, 10);
1090 int len
= strlen (value_ptr
);
1091 for (int i
= 0; i
< len
; i
++) {
1092 ok
= (isspace (value_ptr
[i
]) != 0);
1093 if (!ok
) return FALSE
;
1099 char *wxPropertyValidator::FloatToString (float number
) {
1100 static char buf
[20];
1101 sprintf (buf
, "%.6g", number
);
1105 char *wxPropertyValidator::DoubleToString (double number
) {
1106 static char buf
[20];
1107 sprintf (buf
, "%.6g", number
);
1111 char *wxPropertyValidator::IntToString (int number
) {
1112 return ::IntToString (number
);
1115 char *wxPropertyValidator::LongToString (long number
) {
1116 return ::LongToString (number
);