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