]> git.saurik.com Git - wxWidgets.git/blob - src/common/variant.cpp
Added rules to build the regex library from the main makefile, if
[wxWidgets.git] / src / common / variant.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        variant.cpp
3 // Purpose:     wxVariant class, container for any type
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     10/09/98
7 // RCS-ID:      $Id$
8 // Copyright:   (c)
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "variant.h"
14 #pragma implementation "time.h"
15 #pragma implementation "date.h"
16 #endif
17
18 // For compilers that support precompilation, includes "wx/wx.h".
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22     #pragma hdrstop
23 #endif
24
25 #if wxUSE_STD_IOSTREAM
26     #if wxUSE_IOSTREAMH
27         #include <fstream.h>
28     #else
29         #include <fstream>
30     #endif
31 #endif
32
33 #if wxUSE_STREAMS
34 #include "wx/stream.h"
35 #include "wx/txtstrm.h"
36 #endif
37
38 #include "wx/string.h"
39 #include "wx/variant.h"
40
41 #if wxUSE_TIMEDATE
42 IMPLEMENT_DYNAMIC_CLASS(wxDate, wxObject)
43 IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
44
45 wxTime::tFormat    wxTime::ms_Format    = wxTime::wx12h;
46 wxTime::tPrecision wxTime::ms_Precision  = wxTime::wxStdMinSec;
47 wxChar             wxTime::ms_bufTime[128];
48 #endif
49
50 IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
51
52 wxVariant WXDLLEXPORT wxNullVariant;
53
54 /*
55  * wxVariantDataList
56  */
57
58 class WXDLLEXPORT wxVariantDataList: public wxVariantData
59 {
60 DECLARE_DYNAMIC_CLASS(wxVariantDataList)
61 public:
62     wxVariantDataList() {}
63     wxVariantDataList(const wxList& list);
64     ~wxVariantDataList();
65
66     wxList& GetValue() const { return (wxList&) m_value; }
67     void SetValue(const wxList& value) ;
68
69     virtual void Copy(wxVariantData& data);
70     virtual bool Eq(wxVariantData& data) const;
71 #if wxUSE_STD_IOSTREAM
72     virtual bool Write(wxSTD ostream& str) const;
73 #endif
74     virtual bool Write(wxString& str) const;
75 #if wxUSE_STD_IOSTREAM
76     virtual bool Read(wxSTD istream& str);
77 #endif
78     virtual bool Read(wxString& str);
79     virtual wxString GetType() const { return wxT("list"); };
80
81     void Clear();
82
83 protected:
84     wxList  m_value;
85 };
86
87 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
88
89 wxVariantDataList::wxVariantDataList(const wxList& list)
90 {
91     SetValue(list);
92 }
93
94 wxVariantDataList::~wxVariantDataList()
95 {
96     Clear();
97 }
98
99 void wxVariantDataList::SetValue(const wxList& value)
100 {
101     Clear();
102     wxNode* node = value.First();
103     while (node)
104     {
105         wxVariant* var = (wxVariant*) node->Data();
106         m_value.Append(new wxVariant(*var));
107         node = node->Next();
108     }
109 }
110
111 void wxVariantDataList::Clear()
112 {
113     wxNode* node = m_value.First();
114     while (node)
115     {
116         wxVariant* var = (wxVariant*) node->Data();
117         delete var;
118         node = node->Next();
119     }
120     m_value.Clear();
121 }
122
123 void wxVariantDataList::Copy(wxVariantData& data)
124 {
125     wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Copy: Can't copy to this type of data") );
126
127     wxVariantDataList& listData = (wxVariantDataList&) data;
128
129     listData.Clear();
130     wxNode* node = m_value.First();
131     while (node)
132     {
133         wxVariant* var = (wxVariant*) node->Data();
134         listData.m_value.Append(new wxVariant(*var));
135         node = node->Next();
136     }
137 }
138
139 bool wxVariantDataList::Eq(wxVariantData& data) const
140 {
141     wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
142
143     wxVariantDataList& listData = (wxVariantDataList&) data;
144     wxNode* node1 = m_value.First();
145     wxNode* node2 = listData.GetValue().First();
146     while (node1 && node2)
147     {
148         wxVariant* var1 = (wxVariant*) node1->Data();
149         wxVariant* var2 = (wxVariant*) node2->Data();
150         if ((*var1) != (*var2))
151             return FALSE;
152         node1 = node1->Next();
153         node2 = node2->Next();
154     }
155     if (node1 || node2) return FALSE;
156     return TRUE;
157 }
158
159 #if wxUSE_STD_IOSTREAM
160 bool wxVariantDataList::Write(wxSTD ostream& str) const
161 {
162     wxString s;
163     Write(s);
164     str << (const char*) s.mb_str();
165     return TRUE;
166 }
167 #endif
168
169 bool wxVariantDataList::Write(wxString& str) const
170 {
171     str = wxT("");
172     wxNode* node = m_value.First();
173     while (node)
174     {
175         wxVariant* var = (wxVariant*) node->Data();
176         if (node != m_value.First())
177           str += wxT(" ");
178         wxString str1;
179         str += var->MakeString();
180         node = node->Next();
181     }
182
183     return TRUE;
184 }
185
186 #if wxUSE_STD_IOSTREAM
187 bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
188 {
189     wxFAIL_MSG(wxT("Unimplemented"));
190     // TODO
191     return FALSE;
192 }
193 #endif
194
195 bool wxVariantDataList::Read(wxString& WXUNUSED(str))
196 {
197     wxFAIL_MSG(wxT("Unimplemented"));
198     // TODO
199     return FALSE;
200 }
201
202 /*
203  * wxVariantDataStringList
204  */
205
206 class WXDLLEXPORT wxVariantDataStringList: public wxVariantData
207 {
208 DECLARE_DYNAMIC_CLASS(wxVariantDataStringList)
209 public:
210     wxVariantDataStringList() {}
211     wxVariantDataStringList(const wxStringList& list) { m_value = list; }
212
213     wxStringList& GetValue() const { return (wxStringList&) m_value; }
214     void SetValue(const wxStringList& value);
215
216     virtual void Copy(wxVariantData& data);
217     virtual bool Eq(wxVariantData& data) const;
218 #if wxUSE_STD_IOSTREAM
219     virtual bool Write(wxSTD ostream& str) const;
220 #endif
221     virtual bool Write(wxString& str) const;
222 #if wxUSE_STD_IOSTREAM
223     virtual bool Read(wxSTD istream& str);
224 #endif
225     virtual bool Read(wxString& str);
226     virtual wxString GetType() const { return wxT("stringlist"); };
227
228 protected:
229     wxStringList  m_value;
230 };
231
232 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData)
233
234 void wxVariantDataStringList::SetValue(const wxStringList& value)
235 {
236     m_value = value;
237 }
238
239 void wxVariantDataStringList::Copy(wxVariantData& data)
240 {
241     wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Copy: Can't copy to this type of data") );
242
243     wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
244
245     listData.m_value = m_value ;
246 }
247
248 bool wxVariantDataStringList::Eq(wxVariantData& data) const
249 {
250     wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Eq: argument mismatch") );
251
252     wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
253     wxNode* node1 = m_value.First();
254     wxNode* node2 = listData.GetValue().First();
255     while (node1 && node2)
256     {
257         wxString str1 ((wxChar*) node1->Data());
258         wxString str2 ((wxChar*) node2->Data());
259         if (str1 != str2)
260             return FALSE;
261         node1 = node1->Next();
262         node2 = node2->Next();
263     }
264     if (node1 || node2) return FALSE;
265     return TRUE;
266 }
267
268 #if wxUSE_STD_IOSTREAM
269 bool wxVariantDataStringList::Write(wxSTD ostream& str) const
270 {
271     wxString s;
272     Write(s);
273     str << (const char*) s.mb_str();
274     return TRUE;
275 }
276 #endif
277
278 bool wxVariantDataStringList::Write(wxString& str) const
279 {
280     str = wxT("");
281     wxNode* node = m_value.First();
282     while (node)
283     {
284         wxChar* s = (wxChar*) node->Data();
285         if (node != m_value.First())
286           str += wxT(" ");
287         str += s;
288         node = node->Next();
289     }
290
291     return TRUE;
292 }
293
294 #if wxUSE_STD_IOSTREAM
295 bool wxVariantDataStringList::Read(wxSTD istream& WXUNUSED(str))
296 {
297     wxFAIL_MSG(wxT("Unimplemented"));
298     // TODO
299     return FALSE;
300 }
301 #endif
302
303 bool wxVariantDataStringList::Read(wxString& WXUNUSED(str))
304 {
305     wxFAIL_MSG(wxT("Unimplemented"));
306     // TODO
307     return FALSE;
308 }
309
310 /*
311  * wxVariantDataLong
312  */
313
314 class WXDLLEXPORT wxVariantDataLong: public wxVariantData
315 {
316 DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
317 public:
318     wxVariantDataLong() { m_value = 0; }
319     wxVariantDataLong(long value) { m_value = value; }
320
321     inline long GetValue() const { return m_value; }
322     inline void SetValue(long value) { m_value = value; }
323
324     virtual void Copy(wxVariantData& data);
325     virtual bool Eq(wxVariantData& data) const;
326
327     virtual bool Read(wxString& str);
328     virtual bool Write(wxString& str) const;
329 #if wxUSE_STD_IOSTREAM
330     virtual bool Read(wxSTD istream& str);
331     virtual bool Write(wxSTD ostream& str) const;
332 #endif
333 #if wxUSE_STREAMS
334     virtual bool Read(wxInputStream& str);
335     virtual bool Write(wxOutputStream &str) const;
336 #endif // wxUSE_STREAMS
337
338     virtual wxString GetType() const { return wxT("long"); };
339
340 protected:
341     long m_value;
342 };
343
344 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
345
346 void wxVariantDataLong::Copy(wxVariantData& data)
347 {
348     wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Copy: Can't copy to this type of data") );
349
350     wxVariantDataLong& otherData = (wxVariantDataLong&) data;
351
352     otherData.m_value = m_value;
353 }
354
355 bool wxVariantDataLong::Eq(wxVariantData& data) const
356 {
357     wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
358
359     wxVariantDataLong& otherData = (wxVariantDataLong&) data;
360
361     return (otherData.m_value == m_value);
362 }
363
364 #if wxUSE_STD_IOSTREAM
365 bool wxVariantDataLong::Write(wxSTD ostream& str) const
366 {
367     wxString s;
368     Write(s);
369     str << (const char*) s.mb_str();
370     return TRUE;
371 }
372 #endif
373
374 bool wxVariantDataLong::Write(wxString& str) const
375 {
376     str.Printf(wxT("%ld"), m_value);
377     return TRUE;
378 }
379
380 #if wxUSE_STD_IOSTREAM
381 bool wxVariantDataLong::Read(wxSTD istream& str)
382 {
383     str >> m_value;
384     return TRUE;
385 }
386 #endif
387
388 #if wxUSE_STREAMS
389 bool wxVariantDataLong::Write(wxOutputStream& str) const
390 {
391     wxTextOutputStream s(str);
392
393     s.Write32((size_t)m_value);
394     return TRUE;
395 }
396
397 bool wxVariantDataLong::Read(wxInputStream& str)
398 {
399    wxTextInputStream s(str);
400    m_value = s.Read32();
401    return TRUE;
402 }
403 #endif // wxUSE_STREAMS
404
405 bool wxVariantDataLong::Read(wxString& str)
406 {
407     m_value = wxAtol((const wxChar*) str);
408     return TRUE;
409 }
410
411 /*
412  * wxVariantDataReal
413  */
414
415 class WXDLLEXPORT wxVariantDataReal: public wxVariantData
416 {
417 DECLARE_DYNAMIC_CLASS(wxVariantDataReal)
418 public:
419     wxVariantDataReal() { m_value = 0.0; }
420     wxVariantDataReal(double value) { m_value = value; }
421
422     inline double GetValue() const { return m_value; }
423     inline void SetValue(double value) { m_value = value; }
424
425     virtual void Copy(wxVariantData& data);
426     virtual bool Eq(wxVariantData& data) const;
427     virtual bool Read(wxString& str);
428 #if wxUSE_STD_IOSTREAM
429     virtual bool Write(wxSTD ostream& str) const;
430 #endif
431     virtual bool Write(wxString& str) const;
432 #if wxUSE_STD_IOSTREAM
433     virtual bool Read(wxSTD istream& str);
434 #endif
435 #if wxUSE_STREAMS
436     virtual bool Read(wxInputStream& str);
437     virtual bool Write(wxOutputStream &str) const;
438 #endif // wxUSE_STREAMS
439     virtual wxString GetType() const { return wxT("double"); };
440
441 protected:
442     double m_value;
443 };
444
445 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataReal, wxVariantData)
446
447 void wxVariantDataReal::Copy(wxVariantData& data)
448 {
449     wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDataReal::Copy: Can't copy to this type of data") );
450
451     wxVariantDataReal& otherData = (wxVariantDataReal&) data;
452
453     otherData.m_value = m_value;
454 }
455
456 bool wxVariantDataReal::Eq(wxVariantData& data) const
457 {
458     wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDataReal::Eq: argument mismatch") );
459
460     wxVariantDataReal& otherData = (wxVariantDataReal&) data;
461
462     return (otherData.m_value == m_value);
463 }
464
465 #if wxUSE_STD_IOSTREAM
466 bool wxVariantDataReal::Write(wxSTD ostream& str) const
467 {
468     wxString s;
469     Write(s);
470     str << (const char*) s.mb_str();
471     return TRUE;
472 }
473 #endif
474
475 bool wxVariantDataReal::Write(wxString& str) const
476 {
477     str.Printf(wxT("%.4f"), m_value);
478     return TRUE;
479 }
480
481 #if wxUSE_STD_IOSTREAM
482 bool wxVariantDataReal::Read(wxSTD istream& str)
483 {
484     str >> m_value;
485     return TRUE;
486 }
487 #endif
488
489 #if wxUSE_STREAMS
490 bool wxVariantDataReal::Write(wxOutputStream& str) const
491 {
492     wxTextOutputStream s(str);
493     s.WriteDouble((double)m_value);
494     return TRUE;
495 }
496
497 bool wxVariantDataReal::Read(wxInputStream& str)
498 {
499     wxTextInputStream s(str);
500     m_value = (float)s.ReadDouble();
501     return TRUE;
502 }
503 #endif // wxUSE_STREAMS
504
505 bool wxVariantDataReal::Read(wxString& str)
506 {
507     m_value = wxAtof((const wxChar*) str);
508     return TRUE;
509 }
510
511 #ifdef HAVE_BOOL
512 /*
513  * wxVariantDataBool
514  */
515
516 class WXDLLEXPORT wxVariantDataBool: public wxVariantData
517 {
518 DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
519 public:
520     wxVariantDataBool() { m_value = 0; }
521     wxVariantDataBool(bool value) { m_value = value; }
522
523     inline bool GetValue() const { return m_value; }
524     inline void SetValue(bool value) { m_value = value; }
525
526     virtual void Copy(wxVariantData& data);
527     virtual bool Eq(wxVariantData& data) const;
528 #if wxUSE_STD_IOSTREAM
529     virtual bool Write(wxSTD ostream& str) const;
530 #endif
531     virtual bool Write(wxString& str) const;
532     virtual bool Read(wxString& str);
533 #if wxUSE_STD_IOSTREAM
534     virtual bool Read(wxSTD istream& str);
535 #endif
536 #if wxUSE_STREAMS
537     virtual bool Read(wxInputStream& str);
538     virtual bool Write(wxOutputStream& str) const;
539 #endif // wxUSE_STREAMS
540     virtual wxString GetType() const { return wxT("bool"); };
541
542 protected:
543     bool m_value;
544 };
545
546 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
547
548 void wxVariantDataBool::Copy(wxVariantData& data)
549 {
550     wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Copy: Can't copy to this type of data") );
551
552     wxVariantDataBool& otherData = (wxVariantDataBool&) data;
553
554     otherData.m_value = m_value;
555 }
556
557 bool wxVariantDataBool::Eq(wxVariantData& data) const
558 {
559     wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
560
561     wxVariantDataBool& otherData = (wxVariantDataBool&) data;
562
563     return (otherData.m_value == m_value);
564 }
565
566 #if wxUSE_STD_IOSTREAM
567 bool wxVariantDataBool::Write(wxSTD ostream& str) const
568 {
569     wxString s;
570     Write(s);
571     str << (const char*) s.mb_str();
572     return TRUE;
573 }
574 #endif
575
576 bool wxVariantDataBool::Write(wxString& str) const
577 {
578     str.Printf(wxT("%d"), (int) m_value);
579     return TRUE;
580 }
581
582 #if wxUSE_STD_IOSTREAM
583 bool wxVariantDataBool::Read(wxSTD istream& WXUNUSED(str))
584 {
585     wxFAIL_MSG(wxT("Unimplemented"));
586 //    str >> (long) m_value;
587     return FALSE;
588 }
589 #endif
590
591 #if wxUSE_STREAMS
592 bool wxVariantDataBool::Write(wxOutputStream& str) const
593 {
594     wxTextOutputStream s(str);
595
596     s.Write8(m_value); 
597     return TRUE;
598 }
599
600 bool wxVariantDataBool::Read(wxInputStream& str)
601 {
602     wxTextInputStream s(str);
603
604     m_value = s.Read8() != 0;
605     return TRUE;
606 }
607 #endif // wxUSE_STREAMS
608
609 bool wxVariantDataBool::Read(wxString& str)
610 {
611     m_value = (wxAtol((const wxChar*) str) != 0);
612     return TRUE;
613 }
614 #endif // HAVE_BOOL
615
616 /*
617  * wxVariantDataChar
618  */
619
620 class WXDLLEXPORT wxVariantDataChar: public wxVariantData
621 {
622 DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
623 public:
624     wxVariantDataChar() { m_value = 0; }
625     wxVariantDataChar(char value) { m_value = value; }
626
627     inline char GetValue() const { return m_value; }
628     inline void SetValue(char value) { m_value = value; }
629
630     virtual void Copy(wxVariantData& data);
631     virtual bool Eq(wxVariantData& data) const;
632 #if wxUSE_STD_IOSTREAM
633     virtual bool Read(wxSTD istream& str);
634     virtual bool Write(wxSTD ostream& str) const;
635 #endif
636     virtual bool Read(wxString& str);
637     virtual bool Write(wxString& str) const;
638 #if wxUSE_STREAMS
639     virtual bool Read(wxInputStream& str);
640     virtual bool Write(wxOutputStream& str) const;
641 #endif // wxUSE_STREAMS
642     virtual wxString GetType() const { return wxT("char"); };
643
644 protected:
645     char m_value;
646 };
647
648 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
649
650 void wxVariantDataChar::Copy(wxVariantData& data)
651 {
652     wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Copy: Can't copy to this type of data") );
653
654     wxVariantDataChar& otherData = (wxVariantDataChar&) data;
655
656     otherData.m_value = m_value;
657 }
658
659 bool wxVariantDataChar::Eq(wxVariantData& data) const
660 {
661     wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
662
663     wxVariantDataChar& otherData = (wxVariantDataChar&) data;
664
665     return (otherData.m_value == m_value);
666 }
667
668 #if wxUSE_STD_IOSTREAM
669 bool wxVariantDataChar::Write(wxSTD ostream& str) const
670 {
671     wxString s;
672     Write(s);
673     str << (const char*) s.mb_str();
674     return TRUE;
675 }
676 #endif
677
678 bool wxVariantDataChar::Write(wxString& str) const
679 {
680     str.Printf(wxT("%c"), m_value);
681     return TRUE;
682 }
683
684 #if wxUSE_STD_IOSTREAM
685 bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
686 {
687     wxFAIL_MSG(wxT("Unimplemented"));
688 //    str >> m_value;
689     return FALSE;
690 }
691 #endif
692
693 #if wxUSE_STREAMS
694 bool wxVariantDataChar::Write(wxOutputStream& str) const
695 {
696     wxTextOutputStream s(str);
697
698     s.Write8(m_value);
699     return TRUE;
700 }
701
702 bool wxVariantDataChar::Read(wxInputStream& str)
703 {
704     wxTextInputStream s(str);
705
706     m_value = s.Read8();
707     return TRUE;
708 }
709 #endif // wxUSE_STREAMS
710
711 bool wxVariantDataChar::Read(wxString& str)
712 {
713     m_value = str[(size_t)0];
714     return TRUE;
715 }
716
717 /*
718  * wxVariantDataString
719  */
720
721 #if defined(__BORLANDC__) && defined(__WIN16__)
722 // Change name because of truncation
723 #define wxVariantDataString wxVariantStringData
724 #endif
725
726 class WXDLLEXPORT wxVariantDataString: public wxVariantData
727 {
728 #if defined(__BORLANDC__) && defined(__WIN16__)
729 DECLARE_DYNAMIC_CLASS(wxVariantStringData)
730 #else
731 DECLARE_DYNAMIC_CLASS(wxVariantDataString)
732 #endif
733 public:
734     wxVariantDataString() { }
735     wxVariantDataString(const wxString& value) { m_value = value; }
736
737     inline wxString GetValue() const { return m_value; }
738     inline void SetValue(const wxString& value) { m_value = value; }
739
740     virtual void Copy(wxVariantData& data);
741     virtual bool Eq(wxVariantData& data) const;
742 #if wxUSE_STD_IOSTREAM
743     virtual bool Write(wxSTD ostream& str) const;
744 #endif
745     virtual bool Read(wxString& str);
746     virtual bool Write(wxString& str) const;
747 #if wxUSE_STD_IOSTREAM
748     virtual bool Read(wxSTD istream& str);
749 #endif
750 #if wxUSE_STREAMS
751     virtual bool Read(wxInputStream& str);
752     virtual bool Write(wxOutputStream& str) const;
753 #endif // wxUSE_STREAMS
754     virtual wxString GetType() const { return wxT("string"); };
755
756 protected:
757     wxString m_value;
758 };
759
760 void wxVariantDataString::Copy(wxVariantData& data)
761 {
762     wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Copy: Can't copy to this type of data") );
763
764     wxVariantDataString& otherData = (wxVariantDataString&) data;
765
766     otherData.m_value = m_value;
767 }
768
769 bool wxVariantDataString::Eq(wxVariantData& data) const
770 {
771     wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
772
773     wxVariantDataString& otherData = (wxVariantDataString&) data;
774
775     return (otherData.m_value == m_value);
776 }
777
778 #if wxUSE_STD_IOSTREAM
779 bool wxVariantDataString::Write(wxSTD ostream& str) const
780 {
781     str << (const char*) m_value.mb_str();
782     return TRUE;
783 }
784 #endif
785
786 bool wxVariantDataString::Write(wxString& str) const
787 {
788     str = m_value;
789     return TRUE;
790 }
791
792 #if wxUSE_STD_IOSTREAM
793 bool wxVariantDataString::Read(wxSTD istream& str)
794 {
795     str >> m_value;
796     return TRUE;
797 }
798 #endif
799
800 #if wxUSE_STREAMS
801 bool wxVariantDataString::Write(wxOutputStream& str) const
802 {
803   // why doesn't wxOutputStream::operator<< take "const wxString&"
804     wxTextOutputStream s(str);
805     s.WriteString(m_value);
806     return TRUE;
807 }
808
809 bool wxVariantDataString::Read(wxInputStream& str)
810 {
811     wxTextInputStream s(str);
812
813     m_value = s.ReadString();
814     return TRUE;
815 }
816 #endif // wxUSE_STREAMS
817
818 bool wxVariantDataString::Read(wxString& str)
819 {
820     m_value = str;
821     return TRUE;
822 }
823
824 #if defined(__BORLANDC__) && defined(__WIN16__)
825 IMPLEMENT_DYNAMIC_CLASS(wxVariantStringData, wxVariantData)
826 #else
827 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
828 #endif
829
830 /*
831  * wxVariantDataTime
832  */
833
834 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
835 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
836
837 class wxVariantDataTime: public wxVariantData
838 {
839  DECLARE_DYNAMIC_CLASS(wxVariantDataTime)
840 public:
841     wxVariantDataTime() { }
842     wxVariantDataTime(const wxTime& value) { m_value = value; }
843
844     inline wxTime GetValue() const { return m_value; }
845     inline void SetValue(const wxTime& value) { m_value = value; }
846
847     virtual void Copy(wxVariantData& data);
848     virtual bool Eq(wxVariantData& data) const;
849 #if wxUSE_STD_IOSTREAM
850     virtual bool Write(wxSTD ostream& str) const;
851 #endif
852     virtual bool Write(wxString& str) const;
853 #if wxUSE_STD_IOSTREAM
854     virtual bool Read(wxSTD istream& str);
855 #endif
856     virtual bool Read(wxString& str);
857     virtual wxString GetType() const { return wxT("time"); };
858         virtual wxVariantData* Clone() { return new wxVariantDataTime; }
859
860 protected:
861     wxTime m_value;
862 };
863
864 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataTime, wxVariantData)
865
866 void wxVariantDataTime::Copy(wxVariantData& data)
867 {
868     wxASSERT_MSG( (data.GetType() == wxT("time")), wxT("wxVariantDataTime::Copy: Can't copy to this type of data") );
869
870     wxVariantDataTime& otherData = (wxVariantDataTime&) data;
871
872     otherData.m_value = m_value;
873 }
874
875 bool wxVariantDataTime::Eq(wxVariantData& data) const
876 {
877     wxASSERT_MSG( (data.GetType() == wxT("time")), wxT("wxVariantDataTime::Eq: argument mismatch") );
878
879     wxVariantDataTime& otherData = (wxVariantDataTime&) data;
880
881     return (otherData.m_value == m_value);
882 }
883
884 #if wxUSE_STD_IOSTREAM
885 bool wxVariantDataTime::Write(wxSTD ostream& str) const
886 {
887     wxString s;
888     Write(s);
889     str << (const char*) s.mb_str();
890     return TRUE;
891 }
892 #endif
893
894 bool wxVariantDataTime::Write(wxString& str) const
895 {
896     wxChar*s = m_value.FormatTime();
897     str = s;
898     return TRUE;
899 }
900
901 #if wxUSE_STD_IOSTREAM
902 bool wxVariantDataTime::Read(wxSTD istream& WXUNUSED(str))
903 {
904     // Not implemented
905     return FALSE;
906 }
907 #endif
908
909 bool wxVariantDataTime::Read(wxString& WXUNUSED(str))
910 {
911     // Not implemented
912     return FALSE;
913 }
914
915 /*
916  * wxVariantDataDate
917  */
918
919 class wxVariantDataDate: public wxVariantData
920 {
921  DECLARE_DYNAMIC_CLASS(wxVariantDataDate)
922 public:
923     wxVariantDataDate() { }
924     wxVariantDataDate(const wxDate& value) { m_value = value; }
925
926     inline wxDate GetValue() const { return m_value; }
927     inline void SetValue(const wxDate& value) { m_value = value; }
928
929     virtual void Copy(wxVariantData& data);
930     virtual bool Eq(wxVariantData& data) const;
931 #if wxUSE_STD_IOSTREAM
932     virtual bool Write(wxSTD ostream& str) const;
933 #endif
934     virtual bool Write(wxString& str) const;
935 #if wxUSE_STD_IOSTREAM
936     virtual bool Read(wxSTD istream& str);
937 #endif
938     virtual bool Read(wxString& str);
939     virtual wxString GetType() const { return wxT("date"); };
940         virtual wxVariantData* Clone() { return new wxVariantDataDate; }
941
942 protected:
943     wxDate m_value;
944 };
945
946 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDate, wxVariantData)
947
948 void wxVariantDataDate::Copy(wxVariantData& data)
949 {
950     wxASSERT_MSG( (data.GetType() == wxT("date")), wxT("wxVariantDataDate::Copy: Can't copy to this type of data") );
951
952     wxVariantDataDate& otherData = (wxVariantDataDate&) data;
953
954     otherData.m_value = m_value;
955 }
956
957 bool wxVariantDataDate::Eq(wxVariantData& data) const
958 {
959     wxASSERT_MSG( (data.GetType() == wxT("date")), wxT("wxVariantDataDate::Eq: argument mismatch") );
960
961     wxVariantDataDate& otherData = (wxVariantDataDate&) data;
962
963     return (otherData.m_value == m_value);
964 }
965
966 #if wxUSE_STD_IOSTREAM
967 bool wxVariantDataDate::Write(wxSTD ostream& str) const
968 {
969     wxString s;
970     Write(s);
971     str << (const char*) s.mb_str();
972     return TRUE;
973 }
974 #endif
975
976 bool wxVariantDataDate::Write(wxString& str) const
977 {
978     str = m_value.FormatDate();
979     return TRUE;
980 }
981
982 #if wxUSE_STD_IOSTREAM
983 bool wxVariantDataDate::Read(wxSTD istream& WXUNUSED(str))
984 {
985     // Not implemented
986     return FALSE;
987 }
988 #endif
989
990 bool wxVariantDataDate::Read(wxString& WXUNUSED(str))
991 {
992     // Not implemented
993     return FALSE;
994 }
995 #endif
996   // wxUSE_TIMEDATE
997
998 /*
999  * wxVariantDataVoidPtr
1000  */
1001
1002 class wxVariantDataVoidPtr: public wxVariantData
1003 {
1004 DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
1005 public:
1006     wxVariantDataVoidPtr() { }
1007     wxVariantDataVoidPtr(void* value) { m_value = value; }
1008
1009     inline void* GetValue() const { return m_value; }
1010     inline void SetValue(void* value) { m_value = value; }
1011
1012     virtual void Copy(wxVariantData& data);
1013     virtual bool Eq(wxVariantData& data) const;
1014 #if wxUSE_STD_IOSTREAM
1015     virtual bool Write(wxSTD ostream& str) const;
1016 #endif
1017     virtual bool Write(wxString& str) const;
1018 #if wxUSE_STD_IOSTREAM
1019     virtual bool Read(wxSTD istream& str);
1020 #endif
1021     virtual bool Read(wxString& str);
1022     virtual wxString GetType() const { return wxT("void*"); };
1023         virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
1024
1025 protected:
1026     void* m_value;
1027 };
1028
1029 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
1030
1031 void wxVariantDataVoidPtr::Copy(wxVariantData& data)
1032 {
1033     wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Copy: Can't copy to this type of data") );
1034
1035     wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1036
1037     otherData.m_value = m_value;
1038 }
1039
1040 bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
1041 {
1042     wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1043
1044     wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1045
1046     return (otherData.m_value == m_value);
1047 }
1048
1049 #if wxUSE_STD_IOSTREAM
1050 bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
1051 {
1052     wxString s;
1053     Write(s);
1054     str << (const char*) s.mb_str();
1055     return TRUE;
1056 }
1057 #endif
1058
1059 bool wxVariantDataVoidPtr::Write(wxString& str) const
1060 {
1061     str.Printf(wxT("%ld"), (long) m_value);
1062     return TRUE;
1063 }
1064
1065 #if wxUSE_STD_IOSTREAM
1066 bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
1067 {
1068     // Not implemented
1069     return FALSE;
1070 }
1071 #endif
1072
1073 bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
1074 {
1075     // Not implemented
1076     return FALSE;
1077 }
1078
1079 /*
1080  * wxVariantDataDateTime
1081  */
1082
1083 class wxVariantDataDateTime: public wxVariantData
1084 {
1085     DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1086
1087 public:
1088     wxVariantDataDateTime() { }
1089     wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1090 #if wxUSE_ODBC
1091     wxVariantDataDateTime(const TIME_STRUCT* valptr) 
1092         { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1093     wxVariantDataDateTime(const DATE_STRUCT* valptr) 
1094         { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1095     wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr) 
1096         { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1097                         valptr->hour, valptr->minute, valptr->second, valptr->fraction ); }
1098 #endif //ODBC
1099
1100     inline wxDateTime GetValue() const { return m_value; }
1101     inline void SetValue(const wxDateTime& value) { m_value = value; }
1102
1103     virtual void Copy(wxVariantData& data);
1104     virtual bool Eq(wxVariantData& data) const;
1105 #if wxUSE_STD_IOSTREAM
1106     virtual bool Write(ostream& str) const;
1107 #endif
1108     virtual bool Write(wxString& str) const;
1109 #if wxUSE_STD_IOSTREAM
1110     virtual bool Read(istream& str);
1111 #endif
1112     virtual bool Read(wxString& str);
1113     virtual wxString GetType() const { return wxT("datetime"); };
1114     virtual wxVariantData* Clone() { return new wxVariantDataDateTime; }
1115
1116 protected:
1117     wxDateTime m_value;
1118 };
1119
1120
1121 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1122
1123 void wxVariantDataDateTime::Copy(wxVariantData& data)
1124 {
1125     wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Copy: Can't copy to this type of data") );
1126
1127     wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1128
1129     otherData.m_value = m_value;
1130 }
1131
1132
1133 bool wxVariantDataDateTime::Eq(wxVariantData& data) const
1134 {
1135     wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1136
1137     wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1138
1139     return (otherData.m_value == m_value);
1140 }
1141
1142
1143 #if wxUSE_STD_IOSTREAM
1144 bool wxVariantDataDateTime::Write(ostream& str) const
1145 {
1146     // Not implemented
1147     return FALSE;
1148 }
1149 #endif
1150
1151
1152 bool wxVariantDataDateTime::Write(wxString& str) const
1153 {
1154     str = m_value.Format();
1155     return TRUE;
1156 }
1157
1158
1159 #if wxUSE_STD_IOSTREAM
1160 bool wxVariantDataDateTime::Read(istream& WXUNUSED(str))
1161 {
1162     // Not implemented
1163     return FALSE;
1164 }
1165 #endif
1166
1167
1168 bool wxVariantDataDateTime::Read(wxString& str)
1169 {
1170     if(! m_value.ParseDateTime(str))
1171         return FALSE;
1172     return TRUE;
1173 }
1174
1175
1176 /*
1177  * wxVariant
1178  */
1179
1180 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
1181
1182 // Construction & destruction
1183 wxVariant::wxVariant()
1184 {
1185     m_data = (wxVariantData*) NULL;
1186 }
1187
1188 wxVariant::wxVariant(double val, const wxString& name)
1189 {
1190     m_data = new wxVariantDataReal(val);
1191     m_name = name;
1192 }
1193
1194 wxVariant::wxVariant(long val, const wxString& name)
1195 {
1196     m_data = new wxVariantDataLong(val);
1197     m_name = name;
1198 }
1199
1200 #ifdef HAVE_BOOL
1201 wxVariant::wxVariant(bool val, const wxString& name)
1202 {
1203     m_data = new wxVariantDataBool(val);
1204     m_name = name;
1205 }
1206 #endif
1207
1208 wxVariant::wxVariant(char val, const wxString& name)
1209 {
1210     m_data = new wxVariantDataChar(val);
1211     m_name = name;
1212 }
1213
1214 wxVariant::wxVariant(const wxString& val, const wxString& name)
1215 {
1216     m_data = new wxVariantDataString(val);
1217     m_name = name;
1218 }
1219
1220 wxVariant::wxVariant(const wxChar* val, const wxString& name)
1221 {
1222     m_data = new wxVariantDataString(wxString(val));
1223     m_name = name;
1224 }
1225
1226 wxVariant::wxVariant(const wxStringList& val, const wxString& name)
1227 {
1228     m_data = new wxVariantDataStringList(val);
1229     m_name = name;
1230 }
1231
1232 wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1233 {
1234     m_data = new wxVariantDataList(val);
1235     m_name = name;
1236 }
1237
1238 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1239 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
1240 wxVariant::wxVariant(const wxTime& val, const wxString& name) // Time
1241 {
1242     m_data = new wxVariantDataTime(val);
1243     m_name = name;
1244 }
1245
1246 wxVariant::wxVariant(const wxDate& val, const wxString& name) // Date
1247 {
1248     m_data = new wxVariantDataDate(val);
1249     m_name = name;
1250 }
1251 #endif
1252
1253 wxVariant::wxVariant(void* val, const wxString& name) // Void ptr
1254 {
1255     m_data = new wxVariantDataVoidPtr(val);
1256     m_name = name;
1257 }
1258
1259 wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1260 {
1261     m_data = new wxVariantDataDateTime(val);
1262     m_name = name;
1263 }
1264
1265 #if wxUSE_ODBC
1266 wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1267 {
1268     m_data = new wxVariantDataDateTime(valptr);
1269     m_name = name;
1270 }
1271
1272 wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1273 {
1274     m_data = new wxVariantDataDateTime(valptr);
1275     m_name = name;
1276 }
1277
1278 wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1279 {
1280     m_data = new wxVariantDataDateTime(valptr);
1281     m_name = name;
1282 }
1283 #endif
1284
1285 wxVariant::wxVariant(const wxVariant& variant)
1286 {
1287     if (!variant.IsNull())
1288     {
1289         m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1290         variant.m_data->Copy(*m_data);
1291     }
1292     else
1293         m_data = (wxVariantData*) NULL;
1294     m_name = variant.m_name;
1295 }
1296
1297 wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
1298 {
1299     m_data = data;
1300     m_name = name;
1301 }
1302
1303 wxVariant::~wxVariant()
1304 {
1305     delete m_data;
1306 }
1307
1308
1309 // Make NULL (i.e. delete the data)
1310 void wxVariant::MakeNull()
1311 {
1312     delete m_data;
1313     m_data = NULL;
1314 }
1315
1316 // Generic operators
1317 // Assignment
1318 void wxVariant::operator= (const wxVariant& variant)
1319 {
1320     if (variant.IsNull())
1321     {
1322         MakeNull();
1323         return;
1324     }
1325
1326     if (IsNull() || (GetType() != variant.GetType()))
1327     {
1328         if (m_data)
1329             delete m_data;
1330         m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1331     }
1332 //    GetData()->Copy(* variant.GetData());
1333     variant.GetData()->Copy(* GetData());
1334 }
1335
1336 // Assignment using data, e.g.
1337 // myVariant = new wxStringVariantData("hello")
1338 void wxVariant::operator= (wxVariantData* variantData)
1339 {
1340     MakeNull();
1341     m_data = variantData;
1342 }
1343
1344 bool wxVariant::operator== (const wxVariant& variant) const
1345 {
1346     if (IsNull() || variant.IsNull())
1347         return (IsNull() == variant.IsNull());
1348
1349     return (GetData()->Eq(* variant.GetData()));
1350 }
1351
1352 bool wxVariant::operator!= (const wxVariant& variant) const
1353 {
1354     return (!(*this == variant));
1355 }
1356
1357
1358 // Specific operators
1359 bool wxVariant::operator== (double value) const
1360 {
1361     double thisValue;
1362     if (!Convert(&thisValue))
1363         return FALSE;
1364     else
1365         return (value == thisValue);
1366 }
1367
1368 bool wxVariant::operator!= (double value) const
1369 {
1370     return (!((*this) == value));
1371 }
1372
1373 void wxVariant::operator= (double value)
1374 {
1375     if (GetType() == wxT("double"))
1376     {
1377         ((wxVariantDataReal*)GetData())->SetValue(value);
1378     }
1379     else
1380     {
1381         if (m_data)
1382             delete m_data;
1383         m_data = new wxVariantDataReal(value);
1384     }
1385 }
1386
1387 bool wxVariant::operator== (long value) const
1388 {
1389     long thisValue;
1390     if (!Convert(&thisValue))
1391         return FALSE;
1392     else
1393         return (value == thisValue);
1394 }
1395
1396 bool wxVariant::operator!= (long value) const
1397 {
1398     return (!((*this) == value));
1399 }
1400
1401 void wxVariant::operator= (long value)
1402 {
1403     if (GetType() == wxT("long"))
1404     {
1405         ((wxVariantDataLong*)GetData())->SetValue(value);
1406     }
1407     else
1408     {
1409         if (m_data)
1410             delete m_data;
1411         m_data = new wxVariantDataLong(value);
1412     }
1413 }
1414
1415 bool wxVariant::operator== (char value) const
1416 {
1417     char thisValue;
1418     if (!Convert(&thisValue))
1419         return FALSE;
1420     else
1421         return (value == thisValue);
1422 }
1423
1424 bool wxVariant::operator!= (char value) const
1425 {
1426     return (!((*this) == value));
1427 }
1428
1429 void wxVariant::operator= (char value)
1430 {
1431     if (GetType() == wxT("char"))
1432     {
1433         ((wxVariantDataChar*)GetData())->SetValue(value);
1434     }
1435     else
1436     {
1437         if (m_data)
1438             delete m_data;
1439         m_data = new wxVariantDataChar(value);
1440     }
1441 }
1442
1443 #ifdef HAVE_BOOL
1444 bool wxVariant::operator== (bool value) const
1445 {
1446     bool thisValue;
1447     if (!Convert(&thisValue))
1448         return FALSE;
1449     else
1450         return (value == thisValue);
1451 }
1452
1453 bool wxVariant::operator!= (bool value) const
1454 {
1455     return (!((*this) == value));
1456 }
1457
1458 void wxVariant::operator= (bool value)
1459 {
1460     if (GetType() == wxT("bool"))
1461     {
1462         ((wxVariantDataBool*)GetData())->SetValue(value);
1463     }
1464     else
1465     {
1466         if (m_data)
1467             delete m_data;
1468         m_data = new wxVariantDataBool(value);
1469     }
1470 }
1471 #endif // HAVE_BOOL
1472
1473 bool wxVariant::operator== (const wxString& value) const
1474 {
1475     wxString thisValue;
1476     if (!Convert(&thisValue))
1477         return FALSE;
1478
1479     return value == thisValue;
1480 }
1481
1482 bool wxVariant::operator!= (const wxString& value) const
1483 {
1484     return (!((*this) == value));
1485 }
1486
1487 void wxVariant::operator= (const wxString& value)
1488 {
1489     if (GetType() == wxT("string"))
1490     {
1491         ((wxVariantDataString*)GetData())->SetValue(value);
1492     }
1493     else
1494     {
1495         if (m_data)
1496             delete m_data;
1497         m_data = new wxVariantDataString(value);
1498     }
1499 }
1500
1501 void wxVariant::operator= (const wxChar* value)
1502 {
1503     if (GetType() == wxT("string"))
1504     {
1505         ((wxVariantDataString*)GetData())->SetValue(wxString(value));
1506     }
1507     else
1508     {
1509         if (m_data)
1510             delete m_data;
1511         m_data = new wxVariantDataString(wxString(value));
1512     }
1513 }
1514
1515 bool wxVariant::operator== (const wxStringList& value) const
1516 {
1517     wxASSERT_MSG( (GetType() == wxT("stringlist")), wxT("Invalid type for == operator") );
1518
1519     wxVariantDataStringList other(value);
1520     return (m_data->Eq(other));
1521 }
1522
1523 bool wxVariant::operator!= (const wxStringList& value) const
1524 {
1525     return (!((*this) == value));
1526 }
1527
1528 void wxVariant::operator= (const wxStringList& value)
1529 {
1530     if (GetType() == wxT("stringlist"))
1531     {
1532         ((wxVariantDataStringList*)GetData())->SetValue(value);
1533     }
1534     else
1535     {
1536         if (m_data)
1537             delete m_data;
1538         m_data = new wxVariantDataStringList(value);
1539     }
1540 }
1541
1542 bool wxVariant::operator== (const wxList& value) const
1543 {
1544     wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1545
1546     wxVariantDataList other(value);
1547     return (m_data->Eq(other));
1548 }
1549
1550 bool wxVariant::operator!= (const wxList& value) const
1551 {
1552     return (!((*this) == value));
1553 }
1554
1555 void wxVariant::operator= (const wxList& value)
1556 {
1557     if (GetType() == wxT("list"))
1558     {
1559         ((wxVariantDataList*)GetData())->SetValue(value);
1560     }
1561     else
1562     {
1563         if (m_data)
1564             delete m_data;
1565         m_data = new wxVariantDataList(value);
1566     }
1567 }
1568
1569 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1570 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
1571 bool wxVariant::operator== (const wxTime& value) const
1572 {
1573     wxTime thisValue;
1574     if (!Convert(&thisValue))
1575         return FALSE;
1576
1577     return value == thisValue;
1578 }
1579
1580 bool wxVariant::operator!= (const wxTime& value) const
1581 {
1582     return (!((*this) == value));
1583 }
1584
1585 void wxVariant::operator= (const wxTime& value)
1586 {
1587     if (GetType() == wxT("time"))
1588     {
1589         ((wxVariantDataTime*)GetData())->SetValue(value);
1590     }
1591     else
1592     {
1593         if (m_data)
1594             delete m_data;
1595         m_data = new wxVariantDataTime(value);
1596     }
1597 }
1598
1599 bool wxVariant::operator== (const wxDate& value) const
1600 {
1601     wxDate thisValue;
1602     if (!Convert(&thisValue))
1603         return FALSE;
1604
1605     return (value == thisValue);
1606 }
1607
1608 bool wxVariant::operator!= (const wxDate& value) const
1609 {
1610     return (!((*this) == value));
1611 }
1612
1613 void wxVariant::operator= (const wxDate& value)
1614 {
1615     if (GetType() == wxT("date"))
1616     {
1617         ((wxVariantDataTime*)GetData())->SetValue(value);
1618     }
1619     else
1620     {
1621         if (m_data)
1622             delete m_data;
1623         m_data = new wxVariantDataDate(value);
1624     }
1625 }
1626 #endif
1627
1628 bool wxVariant::operator== (void* value) const
1629 {
1630     return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1631 }
1632
1633 bool wxVariant::operator!= (void* value) const
1634 {
1635     return (!((*this) == (void*) value));
1636 }
1637
1638 void wxVariant::operator= (void* value)
1639 {
1640     if (GetType() == wxT("void*"))
1641     {
1642         ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1643     }
1644     else
1645     {
1646         if (m_data)
1647             delete m_data;
1648         m_data = new wxVariantDataVoidPtr(value);
1649     }
1650 }
1651
1652 bool wxVariant::operator== (const wxDateTime& value) const
1653 {
1654     wxDateTime thisValue;
1655     if (!Convert(&thisValue))
1656         return FALSE;
1657
1658     return value.IsEqualTo(thisValue);
1659 }
1660
1661 bool wxVariant::operator!= (const wxDateTime& value) const
1662 {
1663     return (!((*this) == value));
1664 }
1665
1666 void wxVariant::operator= (const wxDateTime& value)
1667 {
1668     if (GetType() == wxT("datetime"))
1669     {
1670         ((wxVariantDataDateTime*)GetData())->SetValue(value);
1671     }
1672     else
1673     {
1674         if (m_data)
1675             delete m_data;
1676         m_data = new wxVariantDataDateTime(value);
1677     }
1678 }
1679
1680
1681 #if wxUSE_ODBC
1682 void wxVariant::operator= (const DATE_STRUCT* value)
1683 {
1684     if (m_data)
1685         delete m_data;
1686     m_data = new wxVariantDataDateTime(value);
1687 }
1688
1689
1690 void wxVariant::operator= (const TIME_STRUCT* value)
1691 {
1692     if (m_data)
1693         delete m_data;
1694     m_data = new wxVariantDataDateTime(value);
1695 }
1696
1697
1698 void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1699 {
1700     if (m_data)
1701         delete m_data;
1702     m_data = new wxVariantDataDateTime(value);
1703 }
1704
1705 #endif
1706
1707 // Treat a list variant as an array
1708 wxVariant wxVariant::operator[] (size_t idx) const
1709 {
1710     wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for array operator") );
1711
1712     if (GetType() == wxT("list"))
1713     {
1714         wxVariantDataList* data = (wxVariantDataList*) m_data;
1715         wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
1716         return * (wxVariant*) (data->GetValue().Nth(idx)->Data());
1717     }
1718     else if (GetType() == wxT("stringlist"))
1719     {
1720         wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1721         wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
1722
1723         wxVariant variant( wxString( (wxChar*) (data->GetValue().Nth(idx)->Data()) ));
1724         return variant;
1725     }
1726     return wxNullVariant;
1727 }
1728
1729 wxVariant& wxVariant::operator[] (size_t idx)
1730 {
1731     // We can't return a reference to a variant for a string list, since the string
1732     // is actually stored as a char*, not a variant.
1733
1734     wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1735
1736     wxVariantDataList* data = (wxVariantDataList*) m_data;
1737     wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
1738
1739     return * (wxVariant*) (data->GetValue().Nth(idx)->Data());
1740 }
1741
1742 // Return the number of elements in a list
1743 int wxVariant::GetCount() const
1744 {
1745     wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for GetCount()") );
1746
1747     if (GetType() == wxT("list"))
1748     {
1749         wxVariantDataList* data = (wxVariantDataList*) m_data;
1750         return data->GetValue().Number();
1751     }
1752     else if (GetType() == wxT("stringlist"))
1753     {
1754         wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1755         return data->GetValue().Number();
1756     }
1757     return 0;
1758 }
1759
1760 wxString wxVariant::MakeString() const
1761 {
1762     if (!IsNull())
1763     {
1764         wxString str;
1765         if (GetData()->Write(str))
1766             return str;
1767     }
1768     return wxString(wxT(""));
1769 }
1770
1771 // Accessors
1772
1773 void wxVariant::SetData(wxVariantData* data)
1774 {
1775     if (m_data) delete m_data;
1776     m_data = data;
1777 }
1778
1779
1780 // Returns a string representing the type of the variant,
1781 // e.g. "string", "bool", "stringlist", "list", "double", "long"
1782 wxString wxVariant::GetType() const
1783 {
1784     if (IsNull())
1785         return wxString(wxT("null"));
1786     else
1787         return m_data->GetType();
1788 }
1789
1790
1791 bool wxVariant::IsType(const wxString& type) const
1792 {
1793     return (GetType() == type);
1794 }
1795
1796
1797 // Value accessors
1798 double wxVariant::GetReal() const
1799 {
1800     double value;
1801     if (Convert(& value))
1802         return value;
1803     else
1804     {
1805         wxFAIL_MSG(wxT("Could not convert to a real number"));
1806         return 0.0;
1807     }
1808 }
1809
1810 long wxVariant::GetInteger() const
1811 {
1812     long value;
1813     if (Convert(& value))
1814         return value;
1815     else
1816     {
1817         wxFAIL_MSG(wxT("Could not convert to an integer"));
1818         return 0;
1819     }
1820 }
1821
1822 char wxVariant::GetChar() const
1823 {
1824     char value;
1825     if (Convert(& value))
1826         return value;
1827     else
1828     {
1829         wxFAIL_MSG(wxT("Could not convert to a char"));
1830         return 0;
1831     }
1832 }
1833
1834 bool wxVariant::GetBool() const
1835 {
1836     bool value;
1837     if (Convert(& value))
1838         return value;
1839     else
1840     {
1841         wxFAIL_MSG(wxT("Could not convert to a bool"));
1842         return 0;
1843     }
1844 }
1845
1846 wxString wxVariant::GetString() const
1847 {
1848     wxString value;
1849     if (!Convert(& value))
1850     {
1851         wxFAIL_MSG(wxT("Could not convert to a string"));
1852     }
1853
1854     return value;
1855 }
1856
1857 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1858 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
1859 wxTime wxVariant::GetTime() const
1860 {
1861     wxTime value;
1862     if (!Convert(& value))
1863     {
1864         wxFAIL_MSG(wxT("Could not convert to a time"));
1865     }
1866
1867     return value;
1868 }
1869
1870 wxDate wxVariant::GetDate() const
1871 {
1872     wxDate value;
1873     if (!Convert(& value))
1874     {
1875         wxFAIL_MSG(wxT("Could not convert to a date"));
1876     }
1877
1878     return value;
1879 }
1880 #endif // wxUSE_TIMEDATE
1881
1882 void* wxVariant::GetVoidPtr() const
1883 {
1884     wxASSERT( (GetType() == wxT("void*")) );
1885
1886     return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1887 }
1888
1889 wxDateTime wxVariant::GetDateTime() const
1890 {
1891     wxDateTime value;
1892     if (!Convert(& value))
1893     {
1894         wxFAIL_MSG(wxT("Could not convert to a datetime"));
1895     }
1896
1897     return value;
1898 }
1899
1900 wxList& wxVariant::GetList() const
1901 {
1902     wxASSERT( (GetType() == wxT("list")) );
1903
1904     return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1905 }
1906
1907 wxStringList& wxVariant::GetStringList() const
1908 {
1909     wxASSERT( (GetType() == wxT("stringlist")) );
1910
1911     return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
1912 }
1913
1914 // Append to list
1915 void wxVariant::Append(const wxVariant& value)
1916 {
1917     wxList& list = GetList();
1918
1919     list.Append(new wxVariant(value));
1920 }
1921
1922 // Insert at front of list
1923 void wxVariant::Insert(const wxVariant& value)
1924 {
1925     wxList& list = GetList();
1926
1927     list.Insert(new wxVariant(value));
1928 }
1929
1930 // Returns TRUE if the variant is a member of the list
1931 bool wxVariant::Member(const wxVariant& value) const
1932 {
1933     wxList& list = GetList();
1934
1935     wxNode* node = list.First();
1936     while (node)
1937     {
1938         wxVariant* other = (wxVariant*) node->Data();
1939         if (value == *other)
1940             return TRUE;
1941         node = node->Next();
1942     }
1943     return FALSE;
1944 }
1945
1946 // Deletes the nth element of the list
1947 bool wxVariant::Delete(int item)
1948 {
1949     wxList& list = GetList();
1950
1951     wxASSERT_MSG( (item < list.Number()), wxT("Invalid index to Delete") );
1952     wxNode* node = list.Nth(item);
1953     wxVariant* variant = (wxVariant*) node->Data();
1954     delete variant;
1955     delete node;
1956     return TRUE;
1957 }
1958
1959 // Clear list
1960 void wxVariant::ClearList()
1961 {
1962     if (!IsNull() && (GetType() == wxT("list")))
1963     {
1964         ((wxVariantDataList*) m_data)->Clear();
1965     }
1966     else
1967     {
1968         if (GetType() != wxT("list"))
1969         {
1970             delete m_data;
1971             m_data = NULL;
1972         }
1973         m_data = new wxVariantDataList;
1974     }
1975 }
1976
1977 // Type conversion
1978 bool wxVariant::Convert(long* value) const
1979 {
1980     wxString type(GetType());
1981     if (type == wxT("double"))
1982         *value = (long) (((wxVariantDataReal*)GetData())->GetValue());
1983     else if (type == wxT("long"))
1984         *value = ((wxVariantDataLong*)GetData())->GetValue();
1985 #ifdef HAVE_BOOL
1986     else if (type == wxT("bool"))
1987         *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
1988 #endif
1989     else if (type == wxT("string"))
1990         *value = wxAtol((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
1991     else
1992         return FALSE;
1993
1994     return TRUE;
1995 }
1996
1997 bool wxVariant::Convert(bool* value) const
1998 {
1999     wxString type(GetType());
2000     if (type == wxT("double"))
2001         *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0);
2002     else if (type == wxT("long"))
2003         *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
2004 #ifdef HAVE_BOOL
2005     else if (type == wxT("bool"))
2006         *value = ((wxVariantDataBool*)GetData())->GetValue();
2007 #endif
2008     else if (type == wxT("string"))
2009     {
2010         wxString val(((wxVariantDataString*)GetData())->GetValue());
2011         val.MakeLower();
2012         if (val == wxT("true") || val == wxT("yes"))
2013             *value = TRUE;
2014         else if (val == wxT("false") || val == wxT("no"))
2015             *value = FALSE;
2016         else
2017             return FALSE;
2018     }
2019     else
2020         return FALSE;
2021
2022     return TRUE;
2023 }
2024
2025 bool wxVariant::Convert(double* value) const
2026 {
2027     wxString type(GetType());
2028     if (type == wxT("double"))
2029         *value = ((wxVariantDataReal*)GetData())->GetValue();
2030     else if (type == wxT("long"))
2031         *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
2032 #ifdef HAVE_BOOL
2033     else if (type == wxT("bool"))
2034         *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
2035 #endif
2036     else if (type == wxT("string"))
2037         *value = (double) wxAtof((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2038     else
2039         return FALSE;
2040
2041     return TRUE;
2042 }
2043
2044 bool wxVariant::Convert(char* value) const
2045 {
2046     wxString type(GetType());
2047     if (type == wxT("char"))
2048         *value = ((wxVariantDataChar*)GetData())->GetValue();
2049     else if (type == wxT("long"))
2050         *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
2051 #ifdef HAVE_BOOL
2052     else if (type == wxT("bool"))
2053         *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
2054 #endif
2055     else
2056         return FALSE;
2057
2058     return TRUE;
2059 }
2060
2061 bool wxVariant::Convert(wxString* value) const
2062 {
2063     *value = MakeString();
2064     return TRUE;
2065 }
2066
2067 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
2068 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
2069 bool wxVariant::Convert(wxTime* value) const
2070 {
2071     wxString type(GetType());
2072     if (type == wxT("time"))
2073         *value = ((wxVariantDataTime*)GetData())->GetValue();
2074     else if (type == wxT("date"))
2075         *value = wxTime(((wxVariantDataDate*)GetData())->GetValue());
2076     else
2077         return FALSE;
2078
2079     return TRUE;
2080 }
2081
2082 bool wxVariant::Convert(wxDate* value) const
2083 {
2084     wxString type(GetType());
2085     if (type == wxT("date"))
2086         *value = ((wxVariantDataDate*)GetData())->GetValue();
2087     else
2088         return FALSE;
2089
2090     return TRUE;
2091 }
2092 #endif // wxUSE_TIMEDATE
2093
2094 bool wxVariant::Convert(wxDateTime* value) const
2095 {
2096     wxString type(GetType());
2097     if (type == wxT("datetime"))
2098         *value = ((wxVariantDataDateTime*)GetData())->GetValue();
2099     else
2100         return FALSE;
2101
2102     return TRUE;
2103 }