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