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