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