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