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