1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Propert sheet classes implementation
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
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"
48 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValue
, wxObject
)
50 wxPropertyValue::wxPropertyValue(void)
52 m_type
= wxPropertyValueNull
;
57 m_modifiedFlag
= FALSE
;
60 wxPropertyValue::wxPropertyValue(const wxPropertyValue
& copyFrom
)
62 m_modifiedFlag
= FALSE
;
63 Copy((wxPropertyValue
& )copyFrom
);
66 wxPropertyValue::wxPropertyValue(const char *val
)
68 m_modifiedFlag
= FALSE
;
69 m_type
= wxPropertyValueString
;
71 m_value
.string
= copystring(val
);
77 wxPropertyValue::wxPropertyValue(const wxString
& val
)
79 m_modifiedFlag
= FALSE
;
80 m_type
= wxPropertyValueString
;
82 m_value
.string
= copystring((const char *)val
);
88 wxPropertyValue::wxPropertyValue(long the_integer
)
90 m_modifiedFlag
= FALSE
;
91 m_type
= wxPropertyValueInteger
;
92 m_value
.integer
= the_integer
;
97 wxPropertyValue::wxPropertyValue(bool val
)
99 m_modifiedFlag
= FALSE
;
100 m_type
= wxPropertyValuebool
;
101 m_value
.integer
= val
;
106 wxPropertyValue::wxPropertyValue(float the_real
)
108 m_modifiedFlag
= FALSE
;
109 m_type
= wxPropertyValueReal
;
110 m_value
.real
= the_real
;
115 wxPropertyValue::wxPropertyValue(double the_real
)
117 m_modifiedFlag
= FALSE
;
118 m_type
= wxPropertyValueReal
;
119 m_value
.real
= (float)the_real
;
124 // Pointer versions: we have a pointer to the real C++ value.
125 wxPropertyValue::wxPropertyValue(char **val
)
127 m_modifiedFlag
= FALSE
;
128 m_type
= wxPropertyValueStringPtr
;
130 m_value
.stringPtr
= val
;
136 wxPropertyValue::wxPropertyValue(long *val
)
138 m_modifiedFlag
= FALSE
;
139 m_type
= wxPropertyValueIntegerPtr
;
140 m_value
.integerPtr
= val
;
145 wxPropertyValue::wxPropertyValue(bool *val
)
147 m_modifiedFlag
= FALSE
;
148 m_type
= wxPropertyValueboolPtr
;
149 m_value
.boolPtr
= val
;
154 wxPropertyValue::wxPropertyValue(float *val
)
156 m_modifiedFlag
= FALSE
;
157 m_type
= wxPropertyValueRealPtr
;
158 m_value
.realPtr
= val
;
163 wxPropertyValue::wxPropertyValue(wxList
*the_list
)
165 m_modifiedFlag
= FALSE
;
166 m_type
= wxPropertyValueList
;
169 m_value
.first
= NULL
;
171 wxNode
*node
= the_list
->First();
174 wxPropertyValue
*expr
= (wxPropertyValue
*)node
->Data();
182 wxPropertyValue::wxPropertyValue(wxStringList
*the_list
)
184 m_modifiedFlag
= FALSE
;
185 m_type
= wxPropertyValueList
;
188 m_value
.first
= NULL
;
190 wxNode
*node
= the_list
->First();
193 char *s
= (char *)node
->Data();
194 Append(new wxPropertyValue(s
));
200 wxPropertyValue::~wxPropertyValue(void)
204 case wxPropertyValueInteger
:
205 case wxPropertyValuebool
:
206 case wxPropertyValueReal
:
210 case wxPropertyValueString
:
212 delete[] m_value
.string
;
215 case wxPropertyValueList
:
217 wxPropertyValue
*expr
= m_value
.first
;
220 wxPropertyValue
*expr1
= expr
->m_next
;
228 case wxPropertyValueNull
: break;
232 void wxPropertyValue::Append(wxPropertyValue
*expr
)
234 m_modifiedFlag
= TRUE
;
236 m_value
.first
= expr
;
239 m_last
->m_next
= expr
;
243 void wxPropertyValue::Insert(wxPropertyValue
*expr
)
245 m_modifiedFlag
= TRUE
;
246 expr
->m_next
= m_value
.first
;
247 m_value
.first
= expr
;
254 void wxPropertyValue::Delete(wxPropertyValue
*node
)
256 wxPropertyValue
*expr
= GetFirst();
258 wxPropertyValue
*previous
= NULL
;
259 while (expr
&& (expr
!= node
))
262 expr
= expr
->GetNext();
268 previous
->m_next
= expr
->m_next
;
270 // If node was the first in the list,
271 // make the list point to the NEXT one.
272 if (GetFirst() == expr
)
274 m_value
.first
= expr
->m_next
;
277 // If node was the last in the list,
278 // make the list 'last' pointer point to the PREVIOUS one.
279 if (GetLast() == expr
)
286 m_modifiedFlag
= TRUE
;
292 void wxPropertyValue::ClearList(void)
294 wxPropertyValue
*val
= GetFirst();
296 m_modifiedFlag
= TRUE
;
300 wxPropertyValue
*next
= val
->GetNext();
304 m_value
.first
= NULL
;
308 wxPropertyValue
*wxPropertyValue::NewCopy(void) const
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
:
322 wxPropertyValue
*expr
= m_value
.first
;
323 wxPropertyValue
*new_list
= new wxPropertyValue
;
324 new_list
->SetType(wxPropertyValueList
);
327 wxPropertyValue
*expr2
= expr
->NewCopy();
328 new_list
->Append(expr2
);
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
);
342 case wxPropertyValueNull
:
344 cerr
<< "Should never get here!\n";
351 void wxPropertyValue::Copy(wxPropertyValue
& copyFrom
)
353 m_type
= copyFrom
.Type();
357 case wxPropertyValueInteger
:
358 (*this) = copyFrom
.IntegerValue();
361 case wxPropertyValueReal
:
362 (*this) = copyFrom
.RealValue();
365 case wxPropertyValueString
:
366 (*this) = wxString(copyFrom
.StringValue());
369 case wxPropertyValuebool
:
370 (*this) = copyFrom
.BoolValue();
374 case wxPropertyValueboolPtr
:
375 (*this) = copyFrom
.BoolValuePtr();
377 case wxPropertyValueRealPtr
:
378 (*this) = copyFrom
.RealValuePtr();
380 case wxPropertyValueIntegerPtr
:
381 (*this) = copyFrom
.IntegerValuePtr();
383 case wxPropertyValueStringPtr
:
385 char** s
= copyFrom
.StringValuePtr();
390 case wxPropertyValueList
:
392 m_value
.first
= NULL
;
395 wxPropertyValue
*expr
= copyFrom
.m_value
.first
;
398 wxPropertyValue
*expr2
= expr
->NewCopy();
404 case wxPropertyValueNull
:
406 cerr
<< "Should never get here!\n";
412 // Return nth argument of a clause (starting from 1)
413 wxPropertyValue
*wxPropertyValue::Arg(wxPropertyValueType type
, int arg
) const
415 wxPropertyValue
*expr
= m_value
.first
;
416 for (int i
= 1; i
< arg
; i
++)
420 if (expr
&& (expr
->m_type
== type
))
426 // Return nth argument of a list expression (starting from zero)
427 wxPropertyValue
*wxPropertyValue::Nth(int arg
) const
429 if (m_type
!= wxPropertyValueList
)
432 wxPropertyValue
*expr
= m_value
.first
;
433 for (int i
= 0; i
< arg
; i
++)
444 // Returns the number of elements in a list expression
445 int wxPropertyValue::Number(void) const
447 if (m_type
!= wxPropertyValueList
)
451 wxPropertyValue
*expr
= m_value
.first
;
460 void wxPropertyValue::WritePropertyClause(ostream
& stream
) // Write this expression as a top-level clause
462 if (m_type
!= wxPropertyValueList
)
465 wxPropertyValue
*node
= m_value
.first
;
468 node
->WritePropertyType(stream
);
476 node
->WritePropertyType(stream
);
478 if (node
) stream
<< ",\n";
485 void wxPropertyValue::WritePropertyType(ostream
& stream
) // Write as any other subexpression
489 case wxPropertyValueInteger
:
491 stream
<< m_value
.integer
;
494 case wxPropertyValueIntegerPtr
:
496 stream
<< *m_value
.integerPtr
;
499 case wxPropertyValuebool
:
507 case wxPropertyValueboolPtr
:
509 if (*m_value
.integerPtr
)
515 case wxPropertyValueReal
:
517 float f
= m_value
.real
;
518 sprintf(wxBuffer
, "%.6g", (double)f
);
522 case wxPropertyValueRealPtr
:
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)
530 sprintf(wxBuffer
, "%.6g", f
);
534 case wxPropertyValueString
:
538 int len
= strlen(m_value
.string
);
539 for (i
= 0; i
< len
; i
++)
541 char ch
= m_value
.string
[i
];
542 // if (ch == '"' || ch == '\\')
550 case wxPropertyValueStringPtr
:
552 wxFAIL_MSG( "wxPropertyValue::WritePropertyType( wxPropertyValueStringPtr ) not implemented" );
555 int len = strlen(*(m_value.stringPtr));
556 for (i = 0; i < len; i++)
558 char ch = *(m_value.stringPtr)[i];
564 case wxPropertyValueList
:
570 wxPropertyValue
*expr
= m_value
.first
;
575 expr
->WritePropertyType(stream
);
577 if (expr
) stream
<< ", ";
583 case wxPropertyValueNull
: break;
587 wxString
wxPropertyValue::GetStringRepresentation(void)
592 ostrstream
str((char *)buf
, (int)500, ios::out
);
593 WritePropertyType(str
);
597 wxString
theString(buf
);
601 void wxPropertyValue::operator=(const wxPropertyValue
& val
)
603 m_modifiedFlag
= TRUE
;
604 Copy((wxPropertyValue
&)val
);
607 // void wxPropertyValue::operator=(const char *val)
608 void wxPropertyValue::operator=(const wxString
& val1
)
610 const char *val
= (const char *)val1
;
612 m_modifiedFlag
= TRUE
;
613 if (m_type
== wxPropertyValueNull
)
614 m_type
= wxPropertyValueString
;
616 if (m_type
== wxPropertyValueString
)
619 m_value
.string
= copystring(val
);
621 m_value
.string
= NULL
;
623 else if (m_type
== wxPropertyValueStringPtr
)
625 if (*m_value
.stringPtr
)
626 delete[] *m_value
.stringPtr
;
628 *m_value
.stringPtr
= copystring(val
);
630 *m_value
.stringPtr
= NULL
;
639 void wxPropertyValue::operator=(const long val
)
641 m_modifiedFlag
= TRUE
;
642 if (m_type
== wxPropertyValueNull
)
643 m_type
= wxPropertyValueInteger
;
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
;
658 void wxPropertyValue::operator=(const bool val
)
660 m_modifiedFlag
= TRUE
;
661 if (m_type
== wxPropertyValueNull
)
662 m_type
= wxPropertyValuebool
;
664 if (m_type
== wxPropertyValuebool
)
665 m_value
.integer
= (long)val
;
666 else if (m_type
== wxPropertyValueboolPtr
)
667 *m_value
.boolPtr
= val
;
673 void wxPropertyValue::operator=(const float val
)
675 m_modifiedFlag
= TRUE
;
676 if (m_type
== wxPropertyValueNull
)
677 m_type
= wxPropertyValueReal
;
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
)
685 else if (m_type
== wxPropertyValueRealPtr
)
686 *m_value
.realPtr
= val
;
692 void wxPropertyValue::operator=(const char **val
)
694 m_modifiedFlag
= TRUE
;
695 m_type
= wxPropertyValueStringPtr
;
698 m_value
.stringPtr
= (char **)val
;
700 m_value
.stringPtr
= NULL
;
707 void wxPropertyValue::operator=(const long *val
)
709 m_modifiedFlag
= TRUE
;
710 m_type
= wxPropertyValueIntegerPtr
;
711 m_value
.integerPtr
= (long *)val
;
716 void wxPropertyValue::operator=(const bool *val
)
718 m_modifiedFlag
= TRUE
;
719 m_type
= wxPropertyValueboolPtr
;
720 m_value
.boolPtr
= (bool *)val
;
725 void wxPropertyValue::operator=(const float *val
)
727 m_modifiedFlag
= TRUE
;
728 m_type
= wxPropertyValueRealPtr
;
729 m_value
.realPtr
= (float *)val
;
734 long wxPropertyValue::IntegerValue(void) const
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
);
747 long *wxPropertyValue::IntegerValuePtr(void) const
749 return m_value
.integerPtr
;
752 float wxPropertyValue::RealValue(void) const {
753 if (m_type
== wxPropertyValueReal
)
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
);
764 float *wxPropertyValue::RealValuePtr(void) const
766 return m_value
.realPtr
;
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);
785 bool *wxPropertyValue::BoolValuePtr(void) const
787 return m_value
.boolPtr
;
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
);
798 char **wxPropertyValue::StringValuePtr(void) const
800 return m_value
.stringPtr
;
804 * A property (name plus value)
807 IMPLEMENT_DYNAMIC_CLASS(wxProperty
, wxObject
)
809 wxProperty::wxProperty(void)
811 m_propertyRole
= (char *)NULL
;
812 m_propertyValidator
= NULL
;
813 m_propertyWindow
= NULL
;
817 wxProperty::wxProperty(wxProperty
& copyFrom
)
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
;
827 wxProperty::wxProperty(wxString nm
, wxString role
, wxPropertyValidator
*ed
):m_name(nm
), m_propertyRole(role
)
829 m_propertyValidator
= ed
;
830 m_propertyWindow
= NULL
;
834 wxProperty::wxProperty(wxString nm
, const wxPropertyValue
& val
, wxString role
, wxPropertyValidator
*ed
):
835 m_value(val
), m_name(nm
), m_propertyRole(role
)
837 m_propertyValidator
= ed
;
838 m_propertyWindow
= NULL
;
842 wxProperty::~wxProperty(void)
844 if (m_propertyValidator
)
845 delete m_propertyValidator
;
848 wxPropertyValue
& wxProperty::GetValue(void) const
850 return (wxPropertyValue
&) m_value
;
853 wxPropertyValidator
*wxProperty::GetValidator(void) const
855 return m_propertyValidator
;
858 wxString
& wxProperty::GetName(void) const
860 return (wxString
&) m_name
;
863 wxString
& wxProperty::GetRole(void) const
865 return (wxString
&) m_propertyRole
;
868 void wxProperty::SetValue(const wxPropertyValue
& val
)
873 void wxProperty::SetValidator(wxPropertyValidator
*ed
)
875 m_propertyValidator
= ed
;
878 void wxProperty::SetRole(wxString
& role
)
880 m_propertyRole
= role
;
883 void wxProperty::SetName(wxString
& nm
)
888 void wxProperty::operator=(const wxPropertyValue
& val
)
894 * Base property view class
897 IMPLEMENT_DYNAMIC_CLASS(wxPropertyView
, wxEvtHandler
)
899 wxPropertyView::wxPropertyView(long flags
)
901 m_buttonFlags
= flags
;
902 m_propertySheet
= NULL
;
903 m_currentValidator
= NULL
;
904 m_currentProperty
= NULL
;
907 wxPropertyView::~wxPropertyView(void)
911 void wxPropertyView::AddRegistry(wxPropertyValidatorRegistry
*registry
)
913 m_validatorRegistryList
.Append(registry
);
916 wxPropertyValidator
*wxPropertyView::FindPropertyValidator(wxProperty
*property
)
918 if (property
->GetValidator())
919 return property
->GetValidator();
921 wxNode
*node
= m_validatorRegistryList
.First();
924 wxPropertyValidatorRegistry
*registry
= (wxPropertyValidatorRegistry
*)node
->Data();
925 wxPropertyValidator
*validator
= registry
->GetValidator(property
->GetRole());
932 if (!wxDefaultPropertyValidator)
933 wxDefaultPropertyValidator = new wxPropertyListValidator;
934 return wxDefaultPropertyValidator;
942 IMPLEMENT_DYNAMIC_CLASS(wxPropertySheet
, wxObject
)
944 wxPropertySheet::wxPropertySheet(void):m_properties(wxKEY_STRING
)
948 wxPropertySheet::~wxPropertySheet(void)
953 bool wxPropertySheet::Save( ostream
& WXUNUSED(str
) )
958 bool wxPropertySheet::Load( ostream
& WXUNUSED(str
) )
963 void wxPropertySheet::UpdateAllViews( wxPropertyView
*WXUNUSED(thisView
) )
968 void wxPropertySheet::AddProperty(wxProperty
*property
)
970 m_properties
.Append((const char*) property
->GetName(), property
);
973 // Get property by name
974 wxProperty
*wxPropertySheet::GetProperty(wxString name
)
976 wxNode
*node
= m_properties
.Find((const char*) name
);
980 return (wxProperty
*)node
->Data();
983 // Clear all properties
984 void wxPropertySheet::Clear(void)
986 wxNode
*node
= m_properties
.First();
989 wxProperty
*prop
= (wxProperty
*)node
->Data();
990 wxNode
*next
= node
->Next();
997 // Sets/clears the modified flag for each property value
998 void wxPropertySheet::SetAllModified(bool flag
)
1000 wxNode
*node
= m_properties
.First();
1003 wxProperty
*prop
= (wxProperty
*)node
->Data();
1004 prop
->GetValue().SetModified(flag
);
1005 node
= node
->Next();
1010 * Property validator registry
1014 IMPLEMENT_DYNAMIC_CLASS(wxPropertyValidatorRegistry
, wxHashTable
)
1016 wxPropertyValidatorRegistry::wxPropertyValidatorRegistry(void):wxHashTable(wxKEY_STRING
)
1020 wxPropertyValidatorRegistry::~wxPropertyValidatorRegistry(void)
1025 void wxPropertyValidatorRegistry::RegisterValidator(const wxString
& typeName
, wxPropertyValidator
*validator
)
1027 Put((const char*) typeName
, validator
);
1030 wxPropertyValidator
*wxPropertyValidatorRegistry::GetValidator(const wxString
& typeName
)
1032 return (wxPropertyValidator
*)Get((const char*) typeName
);
1035 void wxPropertyValidatorRegistry::ClearRegistry(void)
1039 while ((node
= Next()))
1041 delete (wxPropertyValidator
*)node
->Data();
1046 * Property validator
1050 IMPLEMENT_ABSTRACT_CLASS(wxPropertyValidator
, wxEvtHandler
)
1052 wxPropertyValidator::wxPropertyValidator(long flags
)
1054 m_validatorFlags
= flags
;
1055 m_validatorProperty
= NULL
;
1058 wxPropertyValidator::~wxPropertyValidator(void)
1061 bool wxPropertyValidator::StringToFloat (char *s
, float *number
) {
1063 bool ok
= StringToDouble (s
, &num
);
1064 *number
= (float) num
;
1068 bool wxPropertyValidator::StringToDouble (char *s
, double *number
) {
1071 *number
= strtod (s
, &value_ptr
);
1073 int len
= strlen (value_ptr
);
1074 for (int i
= 0; i
< len
; i
++) {
1075 ok
= (isspace (value_ptr
[i
]) != 0);
1076 if (!ok
) return FALSE
;
1082 bool wxPropertyValidator::StringToInt (char *s
, int *number
) {
1084 bool ok
= StringToLong (s
, &num
);
1085 *number
= (int) num
;
1089 bool wxPropertyValidator::StringToLong (char *s
, long *number
) {
1092 *number
= strtol (s
, &value_ptr
, 10);
1094 int len
= strlen (value_ptr
);
1095 for (int i
= 0; i
< len
; i
++) {
1096 ok
= (isspace (value_ptr
[i
]) != 0);
1097 if (!ok
) return FALSE
;
1103 char *wxPropertyValidator::FloatToString (float number
) {
1104 static char buf
[20];
1105 sprintf (buf
, "%.6g", number
);
1109 char *wxPropertyValidator::DoubleToString (double number
) {
1110 static char buf
[20];
1111 sprintf (buf
, "%.6g", number
);
1115 char *wxPropertyValidator::IntToString (int number
) {
1116 return ::IntToString (number
);
1119 char *wxPropertyValidator::LongToString (long number
) {
1120 return ::LongToString (number
);