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