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