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