]> git.saurik.com Git - wxWidgets.git/blob - src/common/variant.cpp
more GetDefaultAttributesFromGTKWidget fixes
[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 class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
717 {
718 DECLARE_DYNAMIC_CLASS(wxVariantDataString)
719 public:
720     wxVariantDataString() { }
721     wxVariantDataString(const wxString& value) { m_value = value; }
722
723     inline wxString GetValue() const { return m_value; }
724     inline void SetValue(const wxString& value) { m_value = value; }
725
726     virtual void Copy(wxVariantData& data);
727     virtual bool Eq(wxVariantData& data) const;
728 #if wxUSE_STD_IOSTREAM
729     virtual bool Write(wxSTD ostream& str) const;
730 #endif
731     virtual bool Read(wxString& str);
732     virtual bool Write(wxString& str) const;
733 #if wxUSE_STD_IOSTREAM
734     virtual bool Read(wxSTD istream& str);
735 #endif
736 #if wxUSE_STREAMS
737     virtual bool Read(wxInputStream& str);
738     virtual bool Write(wxOutputStream& str) const;
739 #endif // wxUSE_STREAMS
740     virtual wxString GetType() const { return wxT("string"); };
741
742 protected:
743     wxString m_value;
744 };
745
746 void wxVariantDataString::Copy(wxVariantData& data)
747 {
748     wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Copy: Can't copy to this type of data") );
749
750     wxVariantDataString& otherData = (wxVariantDataString&) data;
751
752     otherData.m_value = m_value;
753 }
754
755 bool wxVariantDataString::Eq(wxVariantData& data) const
756 {
757     wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
758
759     wxVariantDataString& otherData = (wxVariantDataString&) data;
760
761     return (otherData.m_value == m_value);
762 }
763
764 #if wxUSE_STD_IOSTREAM
765 bool wxVariantDataString::Write(wxSTD ostream& str) const
766 {
767     str << (const char*) m_value.mb_str();
768     return TRUE;
769 }
770 #endif
771
772 bool wxVariantDataString::Write(wxString& str) const
773 {
774     str = m_value;
775     return TRUE;
776 }
777
778 #if wxUSE_STD_IOSTREAM
779 bool wxVariantDataString::Read(wxSTD istream& str)
780 {
781     str >> m_value;
782     return TRUE;
783 }
784 #endif
785
786 #if wxUSE_STREAMS
787 bool wxVariantDataString::Write(wxOutputStream& str) const
788 {
789   // why doesn't wxOutputStream::operator<< take "const wxString&"
790     wxTextOutputStream s(str);
791     s.WriteString(m_value);
792     return TRUE;
793 }
794
795 bool wxVariantDataString::Read(wxInputStream& str)
796 {
797     wxTextInputStream s(str);
798
799     m_value = s.ReadString();
800     return TRUE;
801 }
802 #endif // wxUSE_STREAMS
803
804 bool wxVariantDataString::Read(wxString& str)
805 {
806     m_value = str;
807     return TRUE;
808 }
809
810 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
811
812 /*
813  * wxVariantDataVoidPtr
814  */
815
816 class wxVariantDataVoidPtr: public wxVariantData
817 {
818 DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
819 public:
820     wxVariantDataVoidPtr() { }
821     wxVariantDataVoidPtr(void* value) { m_value = value; }
822
823     inline void* GetValue() const { return m_value; }
824     inline void SetValue(void* value) { m_value = value; }
825
826     virtual void Copy(wxVariantData& data);
827     virtual bool Eq(wxVariantData& data) const;
828 #if wxUSE_STD_IOSTREAM
829     virtual bool Write(wxSTD ostream& str) const;
830 #endif
831     virtual bool Write(wxString& str) const;
832 #if wxUSE_STD_IOSTREAM
833     virtual bool Read(wxSTD istream& str);
834 #endif
835     virtual bool Read(wxString& str);
836     virtual wxString GetType() const { return wxT("void*"); };
837     virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
838
839 protected:
840     void* m_value;
841
842     DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
843 };
844
845 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
846
847 void wxVariantDataVoidPtr::Copy(wxVariantData& data)
848 {
849     wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Copy: Can't copy to this type of data") );
850
851     wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
852
853     otherData.m_value = m_value;
854 }
855
856 bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
857 {
858     wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
859
860     wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
861
862     return (otherData.m_value == m_value);
863 }
864
865 #if wxUSE_STD_IOSTREAM
866 bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
867 {
868     wxString s;
869     Write(s);
870     str << (const char*) s.mb_str();
871     return TRUE;
872 }
873 #endif
874
875 bool wxVariantDataVoidPtr::Write(wxString& str) const
876 {
877     str.Printf(wxT("%ld"), (long) m_value);
878     return TRUE;
879 }
880
881 #if wxUSE_STD_IOSTREAM
882 bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
883 {
884     // Not implemented
885     return FALSE;
886 }
887 #endif
888
889 bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
890 {
891     // Not implemented
892     return FALSE;
893 }
894
895 /*
896  * wxVariantDataWxObjectPtr
897  */
898
899 class wxVariantDataWxObjectPtr: public wxVariantData
900 {
901 DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
902 public:
903     wxVariantDataWxObjectPtr() { }
904     wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
905
906     inline wxObject* GetValue() const { return m_value; }
907     inline void SetValue(wxObject* value) { m_value = value; }
908
909     virtual void Copy(wxVariantData& data);
910     virtual bool Eq(wxVariantData& data) const;
911 #if wxUSE_STD_IOSTREAM
912     virtual bool Write(wxSTD ostream& str) const;
913 #endif
914     virtual bool Write(wxString& str) const;
915 #if wxUSE_STD_IOSTREAM
916     virtual bool Read(wxSTD istream& str);
917 #endif
918     virtual bool Read(wxString& str);
919     virtual wxString GetType() const ;
920     virtual wxVariantData* Clone() { return new wxVariantDataWxObjectPtr; }
921
922     virtual wxClassInfo* GetValueClassInfo() ; 
923 protected:
924     wxObject* m_value;
925
926     DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
927 };
928
929 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
930
931 void wxVariantDataWxObjectPtr::Copy(wxVariantData& data)
932 {
933     wxASSERT_MSG(  wxIsKindOf((&data), wxVariantDataWxObjectPtr) ,\
934                    wxT("wxVariantDataWxObjectPtr::Copy: Can't copy to this type of data") \
935                  );
936
937     wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
938
939     otherData.m_value = m_value;
940 }
941
942 bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
943 {
944     wxASSERT_MSG(   wxIsKindOf((&data), wxVariantDataWxObjectPtr), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
945
946     wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
947
948     return (otherData.m_value == m_value);
949 }
950
951 wxString wxVariantDataWxObjectPtr::GetType() const
952 {
953     wxString returnVal(wxT("wxObject"));
954     if (m_value) {
955         returnVal = m_value->GetClassInfo()->GetClassName();
956     }
957     return returnVal;
958 }
959
960 wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
961 {
962     wxClassInfo* returnVal=NULL;
963     
964     if (m_value) returnVal = m_value->GetClassInfo(); 
965
966     return returnVal;
967 }
968
969 #if wxUSE_STD_IOSTREAM
970 bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
971 {
972     wxString s;
973     Write(s);
974     str << (const char*) s.mb_str();
975     return TRUE;
976 }
977 #endif
978
979 bool wxVariantDataWxObjectPtr::Write(wxString& str) const
980 {
981     str.Printf(wxT("%s(%ld)"), GetType().c_str(), (long) m_value);
982     return TRUE;
983 }
984
985 #if wxUSE_STD_IOSTREAM
986 bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
987 {
988     // Not implemented
989     return FALSE;
990 }
991 #endif
992
993 bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
994 {
995     // Not implemented
996     return FALSE;
997 }
998
999
1000 /*
1001  * wxVariantDataDateTime
1002  */
1003
1004 #if wxUSE_DATETIME
1005
1006 class wxVariantDataDateTime: public wxVariantData
1007 {
1008     DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1009
1010 public:
1011     wxVariantDataDateTime() { }
1012     wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1013 #if wxUSE_ODBC
1014     wxVariantDataDateTime(const TIME_STRUCT* valptr)
1015         { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1016     wxVariantDataDateTime(const DATE_STRUCT* valptr)
1017         { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1018     wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr)
1019         { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1020                         valptr->hour, valptr->minute, valptr->second, valptr->fraction ); }
1021 #endif //ODBC
1022
1023     inline wxDateTime GetValue() const { return m_value; }
1024     inline void SetValue(const wxDateTime& value) { m_value = value; }
1025
1026     virtual void Copy(wxVariantData& data);
1027     virtual bool Eq(wxVariantData& data) const;
1028 #if wxUSE_STD_IOSTREAM
1029     virtual bool Write(wxSTD ostream& str) const;
1030 #endif
1031     virtual bool Write(wxString& str) const;
1032 #if wxUSE_STD_IOSTREAM
1033     virtual bool Read(wxSTD istream& str);
1034 #endif
1035     virtual bool Read(wxString& str);
1036     virtual wxString GetType() const { return wxT("datetime"); };
1037     virtual wxVariantData* Clone() { return new wxVariantDataDateTime; }
1038
1039 protected:
1040     wxDateTime m_value;
1041 };
1042
1043
1044 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1045
1046 void wxVariantDataDateTime::Copy(wxVariantData& data)
1047 {
1048     wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Copy: Can't copy to this type of data") );
1049
1050     wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1051
1052     otherData.m_value = m_value;
1053 }
1054
1055
1056 bool wxVariantDataDateTime::Eq(wxVariantData& data) const
1057 {
1058     wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1059
1060     wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1061
1062     return (otherData.m_value == m_value);
1063 }
1064
1065
1066 #if wxUSE_STD_IOSTREAM
1067 bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
1068 {
1069     // Not implemented
1070     return FALSE;
1071 }
1072 #endif
1073
1074
1075 bool wxVariantDataDateTime::Write(wxString& str) const
1076 {
1077     str = m_value.Format();
1078     return TRUE;
1079 }
1080
1081
1082 #if wxUSE_STD_IOSTREAM
1083 bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1084 {
1085     // Not implemented
1086     return FALSE;
1087 }
1088 #endif
1089
1090
1091 bool wxVariantDataDateTime::Read(wxString& str)
1092 {
1093     if(! m_value.ParseDateTime(str))
1094         return FALSE;
1095     return TRUE;
1096 }
1097
1098 #endif // wxUSE_DATETIME
1099
1100 // ----------------------------------------------------------------------------
1101 // wxVariantDataArrayString
1102 // ----------------------------------------------------------------------------
1103
1104 class wxVariantDataArrayString: public wxVariantData
1105 {
1106 public:
1107     wxVariantDataArrayString() { }
1108     wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
1109
1110     wxArrayString GetValue() const { return m_value; }
1111     void SetValue(const wxArrayString& value) { m_value = value; }
1112
1113     virtual void Copy(wxVariantData& data);
1114     virtual bool Eq(wxVariantData& data) const;
1115 #if wxUSE_STD_IOSTREAM
1116     virtual bool Write(wxSTD ostream& str) const;
1117 #endif
1118     virtual bool Write(wxString& str) const;
1119 #if wxUSE_STD_IOSTREAM
1120     virtual bool Read(wxSTD istream& str);
1121 #endif
1122     virtual bool Read(wxString& str);
1123     virtual wxString GetType() const { return wxT("arrstring"); };
1124     virtual wxVariantData* Clone() { return new wxVariantDataArrayString; }
1125
1126 protected:
1127     wxArrayString m_value;
1128
1129     DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1130 };
1131
1132 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
1133
1134 void wxVariantDataArrayString::Copy(wxVariantData& data)
1135 {
1136     wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Copy: Can't copy to this type of data") );
1137
1138     wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1139
1140     otherData.m_value = m_value;
1141 }
1142
1143
1144 bool wxVariantDataArrayString::Eq(wxVariantData& data) const
1145 {
1146     wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1147
1148     wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1149
1150     return otherData.m_value == m_value;
1151 }
1152
1153
1154 #if wxUSE_STD_IOSTREAM
1155 bool wxVariantDataArrayString::Write(wxSTD ostream& str) const
1156 {
1157     // Not implemented
1158     return FALSE;
1159 }
1160 #endif
1161
1162
1163 bool wxVariantDataArrayString::Write(wxString& str) const
1164 {
1165     size_t count = m_value.GetCount();
1166     for ( size_t n = 0; n < count; n++ )
1167     {
1168         if ( n )
1169             str += _T(';');
1170
1171         str += m_value[n];
1172     }
1173
1174     return TRUE;
1175 }
1176
1177
1178 #if wxUSE_STD_IOSTREAM
1179 bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1180 {
1181     // Not implemented
1182     return FALSE;
1183 }
1184 #endif
1185
1186
1187 bool wxVariantDataArrayString::Read(wxString& str)
1188 {
1189     wxStringTokenizer tk(str, _T(";"));
1190     while ( tk.HasMoreTokens() )
1191     {
1192         m_value.Add(tk.GetNextToken());
1193     }
1194
1195     return TRUE;
1196 }
1197
1198
1199
1200 /*
1201  * wxVariant
1202  */
1203
1204 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
1205
1206 // Construction & destruction
1207 wxVariant::wxVariant()
1208 {
1209     m_data = (wxVariantData*) NULL;
1210 }
1211
1212 wxVariant::wxVariant(double val, const wxString& name)
1213 {
1214     m_data = new wxVariantDataReal(val);
1215     m_name = name;
1216 }
1217
1218 wxVariant::wxVariant(long val, const wxString& name)
1219 {
1220     m_data = new wxVariantDataLong(val);
1221     m_name = name;
1222 }
1223
1224 #ifdef HAVE_BOOL
1225 wxVariant::wxVariant(bool val, const wxString& name)
1226 {
1227     m_data = new wxVariantDataBool(val);
1228     m_name = name;
1229 }
1230 #endif
1231
1232 wxVariant::wxVariant(char val, const wxString& name)
1233 {
1234     m_data = new wxVariantDataChar(val);
1235     m_name = name;
1236 }
1237
1238 wxVariant::wxVariant(const wxString& val, const wxString& name)
1239 {
1240     m_data = new wxVariantDataString(val);
1241     m_name = name;
1242 }
1243
1244 wxVariant::wxVariant(const wxChar* val, const wxString& name)
1245 {
1246     m_data = new wxVariantDataString(wxString(val));
1247     m_name = name;
1248 }
1249
1250 wxVariant::wxVariant(const wxStringList& val, const wxString& name)
1251 {
1252     m_data = new wxVariantDataStringList(val);
1253     m_name = name;
1254 }
1255
1256 wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1257 {
1258     m_data = new wxVariantDataList(val);
1259     m_name = name;
1260 }
1261
1262 wxVariant::wxVariant( void* val, const wxString& name)
1263 {
1264    m_data = new wxVariantDataVoidPtr(val);
1265    m_name = name;
1266 }
1267
1268 wxVariant::wxVariant( wxObject* val, const wxString& name)
1269 {
1270    m_data = new wxVariantDataWxObjectPtr(val);
1271    m_name = name;
1272 }
1273
1274 #if wxUSE_DATETIME
1275 wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1276 {
1277         m_data = new wxVariantDataDateTime(val);
1278         m_name = name;
1279 }
1280 #endif // wxUSE_DATETIME    
1281
1282 #if wxUSE_ODBC
1283 wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1284 {
1285     m_data = new wxVariantDataDateTime(valptr);
1286     m_name = name;
1287 }
1288
1289 wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1290 {
1291     m_data = new wxVariantDataDateTime(valptr);
1292     m_name = name;
1293 }
1294
1295 wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1296 {
1297     m_data = new wxVariantDataDateTime(valptr);
1298     m_name = name;
1299 }
1300 #endif // wxUSE_ODBC
1301
1302 wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1303 {
1304     m_data = new wxVariantDataArrayString(val);
1305     m_name = name;
1306 }
1307
1308 wxVariant::wxVariant(const wxVariant& variant)
1309     : wxObject()
1310 {
1311     if (!variant.IsNull())
1312     {
1313         m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1314         variant.m_data->Copy(*m_data);
1315     }
1316     else
1317         m_data = (wxVariantData*) NULL;
1318     m_name = variant.m_name;
1319 }
1320
1321 wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
1322 {
1323     m_data = data;
1324     m_name = name;
1325 }
1326
1327 wxVariant::~wxVariant()
1328 {
1329     delete m_data;
1330 }
1331
1332
1333 // Make NULL (i.e. delete the data)
1334 void wxVariant::MakeNull()
1335 {
1336     delete m_data;
1337     m_data = NULL;
1338 }
1339
1340 // Generic operators
1341 // Assignment
1342 void wxVariant::operator= (const wxVariant& variant)
1343 {
1344     if (variant.IsNull())
1345     {
1346         MakeNull();
1347         return;
1348     }
1349
1350     if (IsNull() || (GetType() != variant.GetType()))
1351     {
1352         if (m_data)
1353             delete m_data;
1354         m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1355     }
1356
1357     variant.GetData()->Copy(* GetData());
1358
1359     m_name = variant.m_name;
1360 }
1361
1362 // Assignment using data, e.g.
1363 // myVariant = new wxStringVariantData("hello")
1364 void wxVariant::operator= (wxVariantData* variantData)
1365 {
1366     MakeNull();
1367     m_data = variantData;
1368 }
1369
1370 bool wxVariant::operator== (const wxVariant& variant) const
1371 {
1372     if (IsNull() || variant.IsNull())
1373         return (IsNull() == variant.IsNull());
1374
1375     return (GetData()->Eq(* variant.GetData()));
1376 }
1377
1378 bool wxVariant::operator!= (const wxVariant& variant) const
1379 {
1380     return (!(*this == variant));
1381 }
1382
1383
1384 // Specific operators
1385 bool wxVariant::operator== (double value) const
1386 {
1387     double thisValue;
1388     if (!Convert(&thisValue))
1389         return FALSE;
1390     else
1391         return (value == thisValue);
1392 }
1393
1394 bool wxVariant::operator!= (double value) const
1395 {
1396     return (!((*this) == value));
1397 }
1398
1399 void wxVariant::operator= (double value)
1400 {
1401     if (GetType() == wxT("double"))
1402     {
1403         ((wxVariantDataReal*)GetData())->SetValue(value);
1404     }
1405     else
1406     {
1407         if (m_data)
1408             delete m_data;
1409         m_data = new wxVariantDataReal(value);
1410     }
1411 }
1412
1413 bool wxVariant::operator== (long value) const
1414 {
1415     long thisValue;
1416     if (!Convert(&thisValue))
1417         return FALSE;
1418     else
1419         return (value == thisValue);
1420 }
1421
1422 bool wxVariant::operator!= (long value) const
1423 {
1424     return (!((*this) == value));
1425 }
1426
1427 void wxVariant::operator= (long value)
1428 {
1429     if (GetType() == wxT("long"))
1430     {
1431         ((wxVariantDataLong*)GetData())->SetValue(value);
1432     }
1433     else
1434     {
1435         if (m_data)
1436             delete m_data;
1437         m_data = new wxVariantDataLong(value);
1438     }
1439 }
1440
1441 bool wxVariant::operator== (char value) const
1442 {
1443     char thisValue;
1444     if (!Convert(&thisValue))
1445         return FALSE;
1446     else
1447         return (value == thisValue);
1448 }
1449
1450 bool wxVariant::operator!= (char value) const
1451 {
1452     return (!((*this) == value));
1453 }
1454
1455 void wxVariant::operator= (char value)
1456 {
1457     if (GetType() == wxT("char"))
1458     {
1459         ((wxVariantDataChar*)GetData())->SetValue(value);
1460     }
1461     else
1462     {
1463         if (m_data)
1464             delete m_data;
1465         m_data = new wxVariantDataChar(value);
1466     }
1467 }
1468
1469 #ifdef HAVE_BOOL
1470 bool wxVariant::operator== (bool value) const
1471 {
1472     bool thisValue;
1473     if (!Convert(&thisValue))
1474         return FALSE;
1475     else
1476         return (value == thisValue);
1477 }
1478
1479 bool wxVariant::operator!= (bool value) const
1480 {
1481     return (!((*this) == value));
1482 }
1483
1484 void wxVariant::operator= (bool value)
1485 {
1486     if (GetType() == wxT("bool"))
1487     {
1488         ((wxVariantDataBool*)GetData())->SetValue(value);
1489     }
1490     else
1491     {
1492         if (m_data)
1493             delete m_data;
1494         m_data = new wxVariantDataBool(value);
1495     }
1496 }
1497 #endif // HAVE_BOOL
1498
1499 bool wxVariant::operator== (const wxString& value) const
1500 {
1501     wxString thisValue;
1502     if (!Convert(&thisValue))
1503         return FALSE;
1504
1505     return value == thisValue;
1506 }
1507
1508 bool wxVariant::operator!= (const wxString& value) const
1509 {
1510     return (!((*this) == value));
1511 }
1512
1513 void wxVariant::operator= (const wxString& value)
1514 {
1515     if (GetType() == wxT("string"))
1516     {
1517         ((wxVariantDataString*)GetData())->SetValue(value);
1518     }
1519     else
1520     {
1521         if (m_data)
1522             delete m_data;
1523         m_data = new wxVariantDataString(value);
1524     }
1525 }
1526
1527 void wxVariant::operator= (const wxChar* value)
1528 {
1529     if (GetType() == wxT("string"))
1530     {
1531         ((wxVariantDataString*)GetData())->SetValue(wxString(value));
1532     }
1533     else
1534     {
1535         if (m_data)
1536             delete m_data;
1537         m_data = new wxVariantDataString(wxString(value));
1538     }
1539 }
1540
1541 bool wxVariant::operator== (const wxStringList& value) const
1542 {
1543     wxASSERT_MSG( (GetType() == wxT("stringlist")), wxT("Invalid type for == operator") );
1544
1545     wxVariantDataStringList other(value);
1546     return (m_data->Eq(other));
1547 }
1548
1549 bool wxVariant::operator!= (const wxStringList& value) const
1550 {
1551     return (!((*this) == value));
1552 }
1553
1554 void wxVariant::operator= (const wxStringList& value)
1555 {
1556     if (GetType() == wxT("stringlist"))
1557     {
1558         ((wxVariantDataStringList*)GetData())->SetValue(value);
1559     }
1560     else
1561     {
1562         if (m_data)
1563             delete m_data;
1564         m_data = new wxVariantDataStringList(value);
1565     }
1566 }
1567
1568 bool wxVariant::operator== (const wxList& value) const
1569 {
1570     wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1571
1572     wxVariantDataList other(value);
1573     return (m_data->Eq(other));
1574 }
1575
1576 bool wxVariant::operator!= (const wxList& value) const
1577 {
1578     return (!((*this) == value));
1579 }
1580
1581 void wxVariant::operator= (const wxList& value)
1582 {
1583     if (GetType() == wxT("list"))
1584     {
1585         ((wxVariantDataList*)GetData())->SetValue(value);
1586     }
1587     else
1588     {
1589         if (m_data)
1590             delete m_data;
1591         m_data = new wxVariantDataList(value);
1592     }
1593 }
1594
1595 bool wxVariant::operator== (void* value) const
1596 {
1597     return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1598 }
1599
1600 bool wxVariant::operator!= (void* value) const
1601 {
1602     return (!((*this) == (void*) value));
1603 }
1604
1605 void wxVariant::operator= (void* value)
1606 {
1607     if (GetType() == wxT("void*"))
1608     {
1609         ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1610     }
1611     else
1612     {
1613         if (m_data)
1614             delete m_data;
1615         m_data = new wxVariantDataVoidPtr(value);
1616     }
1617 }
1618
1619 #if wxUSE_DATETIME
1620 bool wxVariant::operator== (const wxDateTime& value) const
1621 {
1622     wxDateTime thisValue;
1623     if (!Convert(&thisValue))
1624         return FALSE;
1625
1626     return value.IsEqualTo(thisValue);
1627 }
1628
1629 bool wxVariant::operator!= (const wxDateTime& value) const
1630 {
1631     return (!((*this) == value));
1632 }
1633
1634 void wxVariant::operator= (const wxDateTime& value)
1635 {
1636     if (GetType() == wxT("datetime"))
1637     {
1638         ((wxVariantDataDateTime*)GetData())->SetValue(value);
1639     }
1640     else
1641     {
1642         if (m_data)
1643             delete m_data;
1644         m_data = new wxVariantDataDateTime(value);
1645     }
1646 }
1647 #endif // wxUSE_DATETIME
1648
1649 #if wxUSE_ODBC
1650 void wxVariant::operator= (const DATE_STRUCT* value)
1651 {
1652     if (m_data)
1653         delete m_data;
1654     m_data = new wxVariantDataDateTime(value);
1655 }
1656
1657
1658 void wxVariant::operator= (const TIME_STRUCT* value)
1659 {
1660     if (m_data)
1661         delete m_data;
1662     m_data = new wxVariantDataDateTime(value);
1663 }
1664
1665
1666 void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1667 {
1668     if (m_data)
1669         delete m_data;
1670     m_data = new wxVariantDataDateTime(value);
1671 }
1672
1673 #endif // wxUSE_ODBC
1674
1675 bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1676 {
1677     wxFAIL_MSG( _T("TODO") );
1678
1679     return FALSE;
1680 }
1681
1682 bool wxVariant::operator!=(const wxArrayString& value) const
1683 {
1684     return !(*this == value);
1685 }
1686
1687 void wxVariant::operator=(const wxArrayString& value)
1688 {
1689     if (GetType() == wxT("arrstring"))
1690     {
1691         ((wxVariantDataArrayString *)GetData())->SetValue(value);
1692     }
1693     else
1694     {
1695         delete m_data;
1696         m_data = new wxVariantDataArrayString(value);
1697     }
1698 }
1699
1700 wxArrayString wxVariant::GetArrayString() const
1701 {
1702     if ( GetType() == wxT("arrstring") )
1703         return ((wxVariantDataArrayString *)GetData())->GetValue();
1704
1705     return wxArrayString();
1706 }
1707
1708
1709 // Treat a list variant as an array
1710 wxVariant wxVariant::operator[] (size_t idx) const
1711 {
1712     wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for array operator") );
1713
1714     if (GetType() == wxT("list"))
1715     {
1716         wxVariantDataList* data = (wxVariantDataList*) m_data;
1717         wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1718         return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1719     }
1720     else if (GetType() == wxT("stringlist"))
1721     {
1722         wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1723         wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1724
1725         wxVariant variant( wxString( (const wxChar*) (data->GetValue().Item(idx)->GetData()) ));
1726         return variant;
1727     }
1728     return wxNullVariant;
1729 }
1730
1731 wxVariant& wxVariant::operator[] (size_t idx)
1732 {
1733     // We can't return a reference to a variant for a string list, since the string
1734     // is actually stored as a char*, not a variant.
1735
1736     wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1737
1738     wxVariantDataList* data = (wxVariantDataList*) m_data;
1739     wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1740
1741     return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1742 }
1743
1744 // Return the number of elements in a list
1745 int wxVariant::GetCount() const
1746 {
1747     wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for GetCount()") );
1748
1749     if (GetType() == wxT("list"))
1750     {
1751         wxVariantDataList* data = (wxVariantDataList*) m_data;
1752         return data->GetValue().GetCount();
1753     }
1754     else if (GetType() == wxT("stringlist"))
1755     {
1756         wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1757         return data->GetValue().GetCount();
1758     }
1759     return 0;
1760 }
1761
1762 wxString wxVariant::MakeString() const
1763 {
1764     if (!IsNull())
1765     {
1766         wxString str;
1767         if (GetData()->Write(str))
1768             return str;
1769     }
1770     return wxString(wxT(""));
1771 }
1772
1773 // Accessors
1774
1775 void wxVariant::SetData(wxVariantData* data)
1776 {
1777     if (m_data) delete m_data;
1778     m_data = data;
1779 }
1780
1781
1782 // Returns a string representing the type of the variant,
1783 // e.g. "string", "bool", "stringlist", "list", "double", "long"
1784 wxString wxVariant::GetType() const
1785 {
1786     if (IsNull())
1787         return wxString(wxT("null"));
1788     else
1789         return m_data->GetType();
1790 }
1791
1792
1793 bool wxVariant::IsType(const wxString& type) const
1794 {
1795     return (GetType() == type);
1796 }
1797
1798 bool wxVariant::IsValueKindOf(const wxClassInfo* type) const
1799 {
1800     wxClassInfo* info=m_data->GetValueClassInfo(); 
1801     return info ? info->IsKindOf(type) : false ;
1802 }
1803
1804
1805 // Value accessors
1806 double wxVariant::GetReal() const
1807 {
1808     double value;
1809     if (Convert(& value))
1810         return value;
1811     else
1812     {
1813         wxFAIL_MSG(wxT("Could not convert to a real number"));
1814         return 0.0;
1815     }
1816 }
1817
1818 long wxVariant::GetInteger() const
1819 {
1820     long value;
1821     if (Convert(& value))
1822         return value;
1823     else
1824     {
1825         wxFAIL_MSG(wxT("Could not convert to an integer"));
1826         return 0;
1827     }
1828 }
1829
1830 char wxVariant::GetChar() const
1831 {
1832     char value;
1833     if (Convert(& value))
1834         return value;
1835     else
1836     {
1837         wxFAIL_MSG(wxT("Could not convert to a char"));
1838         return 0;
1839     }
1840 }
1841
1842 bool wxVariant::GetBool() const
1843 {
1844     bool value;
1845     if (Convert(& value))
1846         return value;
1847     else
1848     {
1849         wxFAIL_MSG(wxT("Could not convert to a bool"));
1850         return 0;
1851     }
1852 }
1853
1854 wxString wxVariant::GetString() const
1855 {
1856     wxString value;
1857     if (!Convert(& value))
1858     {
1859         wxFAIL_MSG(wxT("Could not convert to a string"));
1860     }
1861
1862     return value;
1863 }
1864
1865 void* wxVariant::GetVoidPtr() const
1866 {
1867     wxASSERT( (GetType() == wxT("void*")) );
1868
1869     return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1870 }
1871
1872 wxObject* wxVariant::GetWxObjectPtr() 
1873 {
1874     wxASSERT(wxIsKindOf(m_data, wxVariantDataWxObjectPtr));
1875     return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1876 }
1877
1878 #if wxUSE_DATETIME
1879 wxDateTime wxVariant::GetDateTime() const
1880 {
1881     wxDateTime value;
1882     if (!Convert(& value))
1883     {
1884         wxFAIL_MSG(wxT("Could not convert to a datetime"));
1885     }
1886
1887     return value;
1888 }
1889 #endif // wxUSE_DATETIME
1890
1891 wxList& wxVariant::GetList() const
1892 {
1893     wxASSERT( (GetType() == wxT("list")) );
1894
1895     return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1896 }
1897
1898 wxStringList& wxVariant::GetStringList() const
1899 {
1900     wxASSERT( (GetType() == wxT("stringlist")) );
1901
1902     return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
1903 }
1904
1905 // Make empty list
1906 void wxVariant::NullList()
1907 {
1908     SetData(new wxVariantDataList());
1909 };
1910
1911 // Append to list
1912 void wxVariant::Append(const wxVariant& value)
1913 {
1914     wxList& list = GetList();
1915
1916     list.Append(new wxVariant(value));
1917 }
1918
1919 // Insert at front of list
1920 void wxVariant::Insert(const wxVariant& value)
1921 {
1922     wxList& list = GetList();
1923
1924     list.Insert(new wxVariant(value));
1925 }
1926
1927 // Returns TRUE if the variant is a member of the list
1928 bool wxVariant::Member(const wxVariant& value) const
1929 {
1930     wxList& list = GetList();
1931
1932     wxList::compatibility_iterator node = list.GetFirst();
1933     while (node)
1934     {
1935         wxVariant* other = (wxVariant*) node->GetData();
1936         if (value == *other)
1937             return TRUE;
1938         node = node->GetNext();
1939     }
1940     return FALSE;
1941 }
1942
1943 // Deletes the nth element of the list
1944 bool wxVariant::Delete(int item)
1945 {
1946     wxList& list = GetList();
1947
1948     wxASSERT_MSG( (item < (int) list.GetCount()), wxT("Invalid index to Delete") );
1949     wxList::compatibility_iterator node = list.Item(item);
1950     wxVariant* variant = (wxVariant*) node->GetData();
1951     delete variant;
1952     list.Erase(node);
1953     return TRUE;
1954 }
1955
1956 // Clear list
1957 void wxVariant::ClearList()
1958 {
1959     if (!IsNull() && (GetType() == wxT("list")))
1960     {
1961         ((wxVariantDataList*) m_data)->Clear();
1962     }
1963     else
1964     {
1965         if (GetType() != wxT("list"))
1966         {
1967             delete m_data;
1968             m_data = NULL;
1969         }
1970         m_data = new wxVariantDataList;
1971     }
1972 }
1973
1974 // Type conversion
1975 bool wxVariant::Convert(long* value) const
1976 {
1977     wxString type(GetType());
1978     if (type == wxT("double"))
1979         *value = (long) (((wxVariantDataReal*)GetData())->GetValue());
1980     else if (type == wxT("long"))
1981         *value = ((wxVariantDataLong*)GetData())->GetValue();
1982 #ifdef HAVE_BOOL
1983     else if (type == wxT("bool"))
1984         *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
1985 #endif
1986     else if (type == wxT("string"))
1987         *value = wxAtol((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
1988     else
1989         return FALSE;
1990
1991     return TRUE;
1992 }
1993
1994 bool wxVariant::Convert(bool* value) const
1995 {
1996     wxString type(GetType());
1997     if (type == wxT("double"))
1998         *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0);
1999     else if (type == wxT("long"))
2000         *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
2001 #ifdef HAVE_BOOL
2002     else if (type == wxT("bool"))
2003         *value = ((wxVariantDataBool*)GetData())->GetValue();
2004 #endif
2005     else if (type == wxT("string"))
2006     {
2007         wxString val(((wxVariantDataString*)GetData())->GetValue());
2008         val.MakeLower();
2009         if (val == wxT("true") || val == wxT("yes"))
2010             *value = TRUE;
2011         else if (val == wxT("false") || val == wxT("no"))
2012             *value = FALSE;
2013         else
2014             return FALSE;
2015     }
2016     else
2017         return FALSE;
2018
2019     return TRUE;
2020 }
2021
2022 bool wxVariant::Convert(double* value) const
2023 {
2024     wxString type(GetType());
2025     if (type == wxT("double"))
2026         *value = ((wxVariantDataReal*)GetData())->GetValue();
2027     else if (type == wxT("long"))
2028         *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
2029 #ifdef HAVE_BOOL
2030     else if (type == wxT("bool"))
2031         *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
2032 #endif
2033     else if (type == wxT("string"))
2034         *value = (double) wxAtof((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2035     else
2036         return FALSE;
2037
2038     return TRUE;
2039 }
2040
2041 bool wxVariant::Convert(char* value) const
2042 {
2043     wxString type(GetType());
2044     if (type == wxT("char"))
2045         *value = ((wxVariantDataChar*)GetData())->GetValue();
2046     else if (type == wxT("long"))
2047         *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
2048 #ifdef HAVE_BOOL
2049     else if (type == wxT("bool"))
2050         *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
2051 #endif
2052     else
2053         return FALSE;
2054
2055     return TRUE;
2056 }
2057
2058 bool wxVariant::Convert(wxString* value) const
2059 {
2060     *value = MakeString();
2061     return TRUE;
2062 }
2063
2064 #if wxUSE_DATETIME
2065 bool wxVariant::Convert(wxDateTime* value) const
2066 {
2067     wxString type(GetType());
2068     if (type == wxT("datetime"))
2069     {
2070         *value = ((wxVariantDataDateTime*)GetData())->GetValue();
2071         return TRUE;
2072     }
2073     // Fallback to string conversion
2074     wxString val;
2075     return Convert(&val) && (value->ParseDate(val));
2076 }
2077 #endif // wxUSE_DATETIME
2078