]> git.saurik.com Git - wxWidgets.git/blob - src/common/variant.cpp
[ 1577675 ] Fix for GTK warnings in wxNotebook::DoRemovePage
[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 #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
40 namespace std {}
41 using 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
51 IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
52
53 wxVariant WXDLLIMPEXP_BASE wxNullVariant;
54
55
56 /*
57 * wxVariant
58 */
59
60 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
61
62 wxVariant::wxVariant()
63 {
64 m_data = (wxVariantData*) NULL;
65 }
66
67 bool wxVariant::IsNull() const
68 {
69 return (m_data == (wxVariantData*) NULL);
70 }
71
72 void wxVariant::MakeNull()
73 {
74 UnRef();
75 }
76
77 void wxVariant::Clear()
78 {
79 m_name = wxEmptyString;
80 }
81
82 wxVariant::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
93 wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
94 {
95 m_data = data;
96 m_name = name;
97 }
98
99 wxVariant::~wxVariant()
100 {
101 UnRef();
102 }
103
104 // Assignment
105 void wxVariant::operator= (const wxVariant& variant)
106 {
107 Ref(variant);
108 m_name = variant.m_name;
109 }
110
111 // myVariant = new wxStringVariantData("hello")
112 void wxVariant::operator= (wxVariantData* variantData)
113 {
114 UnRef();
115 m_data = variantData;
116 }
117
118 bool 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
126 bool wxVariant::operator!= (const wxVariant& variant) const
127 {
128 return (!(*this == variant));
129 }
130
131
132 wxString 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
143 void wxVariant::SetData(wxVariantData* data)
144 {
145 UnRef();
146 m_data = data;
147 }
148
149 void 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
167 void 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"
181 wxString wxVariant::GetType() const
182 {
183 if (IsNull())
184 return wxString(wxT("null"));
185 else
186 return GetData()->GetType();
187 }
188
189
190 bool wxVariant::IsType(const wxString& type) const
191 {
192 return (GetType() == type);
193 }
194
195 bool 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
206 class WXDLLIMPEXP_BASE wxVariantDataLong: public wxVariantData
207 {
208 DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
209 public:
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
231 protected:
232 long m_value;
233 };
234
235 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
236
237 bool 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
247 bool 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
256 bool wxVariantDataLong::Write(wxString& str) const
257 {
258 str.Printf(wxT("%ld"), m_value);
259 return true;
260 }
261
262 #if wxUSE_STD_IOSTREAM
263 bool wxVariantDataLong::Read(wxSTD istream& str)
264 {
265 str >> m_value;
266 return true;
267 }
268 #endif
269
270 #if wxUSE_STREAMS
271 bool wxVariantDataLong::Write(wxOutputStream& str) const
272 {
273 wxTextOutputStream s(str);
274
275 s.Write32((size_t)m_value);
276 return true;
277 }
278
279 bool wxVariantDataLong::Read(wxInputStream& str)
280 {
281 wxTextInputStream s(str);
282 m_value = s.Read32();
283 return true;
284 }
285 #endif // wxUSE_STREAMS
286
287 bool wxVariantDataLong::Read(wxString& str)
288 {
289 m_value = wxAtol((const wxChar*) str);
290 return true;
291 }
292
293 // wxVariant
294
295 wxVariant::wxVariant(long val, const wxString& name)
296 {
297 m_data = new wxVariantDataLong(val);
298 m_name = name;
299 }
300
301 wxVariant::wxVariant(int val, const wxString& name)
302 {
303 m_data = new wxVariantDataLong((long)val);
304 m_name = name;
305 }
306
307 wxVariant::wxVariant(short val, const wxString& name)
308 {
309 m_data = new wxVariantDataLong((long)val);
310 m_name = name;
311 }
312
313 bool wxVariant::operator== (long value) const
314 {
315 long thisValue;
316 if (!Convert(&thisValue))
317 return false;
318 else
319 return (value == thisValue);
320 }
321
322 bool wxVariant::operator!= (long value) const
323 {
324 return (!((*this) == value));
325 }
326
327 void 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
341 long 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
357 class WXDLLIMPEXP_BASE wxVariantDoubleData: public wxVariantData
358 {
359 DECLARE_DYNAMIC_CLASS(wxVariantDoubleData)
360 public:
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
382 protected:
383 double m_value;
384 };
385
386 IMPLEMENT_DYNAMIC_CLASS(wxVariantDoubleData, wxVariantData)
387
388 bool 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
398 bool 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
407 bool wxVariantDoubleData::Write(wxString& str) const
408 {
409 str.Printf(wxT("%.14g"), m_value);
410 return true;
411 }
412
413 #if wxUSE_STD_IOSTREAM
414 bool wxVariantDoubleData::Read(wxSTD istream& str)
415 {
416 str >> m_value;
417 return true;
418 }
419 #endif
420
421 #if wxUSE_STREAMS
422 bool wxVariantDoubleData::Write(wxOutputStream& str) const
423 {
424 wxTextOutputStream s(str);
425 s.WriteDouble((double)m_value);
426 return true;
427 }
428
429 bool wxVariantDoubleData::Read(wxInputStream& str)
430 {
431 wxTextInputStream s(str);
432 m_value = (float)s.ReadDouble();
433 return true;
434 }
435 #endif // wxUSE_STREAMS
436
437 bool wxVariantDoubleData::Read(wxString& str)
438 {
439 m_value = wxAtof((const wxChar*) str);
440 return true;
441 }
442
443 // wxVariant double code
444
445 wxVariant::wxVariant(double val, const wxString& name)
446 {
447 m_data = new wxVariantDoubleData(val);
448 m_name = name;
449 }
450
451 bool wxVariant::operator== (double value) const
452 {
453 double thisValue;
454 if (!Convert(&thisValue))
455 return false;
456
457 return wxIsSameDouble(value, thisValue);
458 }
459
460 bool wxVariant::operator!= (double value) const
461 {
462 return (!((*this) == value));
463 }
464
465 void 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
479 double 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
497 class WXDLLIMPEXP_BASE wxVariantDataBool: public wxVariantData
498 {
499 DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
500 public:
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
522 protected:
523 bool m_value;
524 };
525
526 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
527
528 bool 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
538 bool 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
547 bool wxVariantDataBool::Write(wxString& str) const
548 {
549 str.Printf(wxT("%d"), (int) m_value);
550 return true;
551 }
552
553 #if wxUSE_STD_IOSTREAM
554 bool 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
563 bool wxVariantDataBool::Write(wxOutputStream& str) const
564 {
565 wxTextOutputStream s(str);
566
567 s.Write8(m_value);
568 return true;
569 }
570
571 bool 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
580 bool wxVariantDataBool::Read(wxString& str)
581 {
582 m_value = (wxAtol((const wxChar*) str) != 0);
583 return true;
584 }
585
586 // wxVariant ****
587
588 wxVariant::wxVariant(bool val, const wxString& name)
589 {
590 m_data = new wxVariantDataBool(val);
591 m_name = name;
592 }
593
594 bool wxVariant::operator== (bool value) const
595 {
596 bool thisValue;
597 if (!Convert(&thisValue))
598 return false;
599 else
600 return (value == thisValue);
601 }
602
603 bool wxVariant::operator!= (bool value) const
604 {
605 return (!((*this) == value));
606 }
607
608 void 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
622 bool 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
640 class WXDLLIMPEXP_BASE wxVariantDataChar: public wxVariantData
641 {
642 DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
643 public:
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
663 protected:
664 wxChar m_value;
665 };
666
667 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
668
669 bool 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
679 bool 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
688 bool wxVariantDataChar::Write(wxString& str) const
689 {
690 str.Printf(wxT("%c"), m_value);
691 return true;
692 }
693
694 #if wxUSE_STD_IOSTREAM
695 bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
696 {
697 wxFAIL_MSG(wxT("Unimplemented"));
698
699 return false;
700 }
701 #endif
702
703 #if wxUSE_STREAMS
704 bool wxVariantDataChar::Write(wxOutputStream& str) const
705 {
706 wxTextOutputStream s(str);
707
708 s << m_value;
709
710 return true;
711 }
712
713 bool wxVariantDataChar::Read(wxInputStream& str)
714 {
715 wxTextInputStream s(str);
716
717 s >> m_value;
718
719 return true;
720 }
721 #endif // wxUSE_STREAMS
722
723 bool wxVariantDataChar::Read(wxString& str)
724 {
725 m_value = str[size_t(0)];
726 return true;
727 }
728
729 wxVariant::wxVariant(wxChar val, const wxString& name)
730 {
731 m_data = new wxVariantDataChar(val);
732 m_name = name;
733 }
734
735 bool wxVariant::operator== (wxChar value) const
736 {
737 wxChar thisValue;
738 if (!Convert(&thisValue))
739 return false;
740 else
741 return (value == thisValue);
742 }
743
744 bool wxVariant::operator!= (wxChar value) const
745 {
746 return (!((*this) == value));
747 }
748
749 void 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
763 wxChar 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
779 class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
780 {
781 DECLARE_DYNAMIC_CLASS(wxVariantDataString)
782 public:
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
804 protected:
805 wxString m_value;
806 };
807
808 bool 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
818 bool wxVariantDataString::Write(wxSTD ostream& str) const
819 {
820 str << (const char*) m_value.mb_str();
821 return true;
822 }
823 #endif
824
825 bool wxVariantDataString::Write(wxString& str) const
826 {
827 str = m_value;
828 return true;
829 }
830
831 #if wxUSE_STREAMS
832 bool 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
840 bool wxVariantDataString::Read(wxInputStream& str)
841 {
842 wxTextInputStream s(str);
843
844 m_value = s.ReadLine();
845 return true;
846 }
847 #endif // wxUSE_STREAMS
848
849 bool wxVariantDataString::Read(wxString& str)
850 {
851 m_value = str;
852 return true;
853 }
854
855 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
856
857 // wxVariant ****
858
859 wxVariant::wxVariant(const wxString& val, const wxString& name)
860 {
861 m_data = new wxVariantDataString(val);
862 m_name = name;
863 }
864
865 wxVariant::wxVariant(const wxChar* val, const wxString& name)
866 {
867 m_data = new wxVariantDataString(wxString(val));
868 m_name = name;
869 }
870
871 bool wxVariant::operator== (const wxString& value) const
872 {
873 wxString thisValue;
874 if (!Convert(&thisValue))
875 return false;
876
877 return value == thisValue;
878 }
879
880 bool wxVariant::operator!= (const wxString& value) const
881 {
882 return (!((*this) == value));
883 }
884
885 void 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
899 void 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
913 wxString 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
928 class wxVariantDataWxObjectPtr: public wxVariantData
929 {
930 DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
931 public:
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() ;
951 protected:
952 wxObject* m_value;
953
954 DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
955 };
956
957 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
958
959 bool 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
968 wxString 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
977 wxClassInfo* 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
987 bool 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
996 bool 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
1003 bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1004 {
1005 // Not implemented
1006 return false;
1007 }
1008 #endif
1009
1010 bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1011 {
1012 // Not implemented
1013 return false;
1014 }
1015
1016 // wxVariant
1017
1018 wxVariant::wxVariant( wxObject* val, const wxString& name)
1019 {
1020 m_data = new wxVariantDataWxObjectPtr(val);
1021 m_name = name;
1022 }
1023
1024 bool wxVariant::operator== (wxObject* value) const
1025 {
1026 return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1027 }
1028
1029 bool wxVariant::operator!= (wxObject* value) const
1030 {
1031 return (!((*this) == (wxObject*) value));
1032 }
1033
1034 void wxVariant::operator= (wxObject* value)
1035 {
1036 UnRef();
1037 m_data = new wxVariantDataWxObjectPtr(value);
1038 }
1039
1040 wxObject* wxVariant::GetWxObjectPtr() const
1041 {
1042 wxASSERT(wxIsKindOf(GetData(), wxVariantDataWxObjectPtr));
1043 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
1044 }
1045
1046 // ----------------------------------------------------------------------------
1047 // wxVariantDataVoidPtr
1048 // ----------------------------------------------------------------------------
1049
1050 class wxVariantDataVoidPtr: public wxVariantData
1051 {
1052 DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
1053 public:
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
1072 protected:
1073 void* m_value;
1074
1075 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
1076 };
1077
1078 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
1079
1080 bool 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
1090 bool 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
1099 bool wxVariantDataVoidPtr::Write(wxString& str) const
1100 {
1101 str.Printf(wxT("%p"), m_value);
1102 return true;
1103 }
1104
1105 #if wxUSE_STD_IOSTREAM
1106 bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
1107 {
1108 // Not implemented
1109 return false;
1110 }
1111 #endif
1112
1113 bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
1114 {
1115 // Not implemented
1116 return false;
1117 }
1118
1119 // wxVariant
1120
1121 wxVariant::wxVariant( void* val, const wxString& name)
1122 {
1123 m_data = new wxVariantDataVoidPtr(val);
1124 m_name = name;
1125 }
1126
1127 bool wxVariant::operator== (void* value) const
1128 {
1129 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1130 }
1131
1132 bool wxVariant::operator!= (void* value) const
1133 {
1134 return (!((*this) == (void*) value));
1135 }
1136
1137 void 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
1151 void* 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
1164 class wxVariantDataDateTime: public wxVariantData
1165 {
1166 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1167
1168 public:
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
1196 protected:
1197 wxDateTime m_value;
1198 };
1199
1200
1201 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1202
1203 bool 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
1214 bool 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
1224 bool wxVariantDataDateTime::Write(wxString& str) const
1225 {
1226 str = m_value.Format();
1227 return true;
1228 }
1229
1230
1231 #if wxUSE_STD_IOSTREAM
1232 bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1233 {
1234 // Not implemented
1235 return false;
1236 }
1237 #endif
1238
1239
1240 bool wxVariantDataDateTime::Read(wxString& str)
1241 {
1242 if(! m_value.ParseDateTime(str))
1243 return false;
1244 return true;
1245 }
1246
1247 // wxVariant
1248
1249 wxVariant::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
1256 wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1257 {
1258 m_data = new wxVariantDataDateTime(valptr);
1259 m_name = name;
1260 }
1261
1262 wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1263 {
1264 m_data = new wxVariantDataDateTime(valptr);
1265 m_name = name;
1266 }
1267
1268 wxVariant::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
1275 bool 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
1284 bool wxVariant::operator!= (const wxDateTime& value) const
1285 {
1286 return (!((*this) == value));
1287 }
1288
1289 void 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
1304 void wxVariant::operator= (const DATE_STRUCT* value)
1305 {
1306 UnRef();
1307 m_data = new wxVariantDataDateTime(value);
1308 }
1309
1310 void wxVariant::operator= (const TIME_STRUCT* value)
1311 {
1312 UnRef();
1313 m_data = new wxVariantDataDateTime(value);
1314 }
1315
1316 void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1317 {
1318 UnRef();
1319 m_data = new wxVariantDataDateTime(value);
1320 }
1321
1322 #endif // wxUSE_ODBC
1323
1324 wxDateTime 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
1341 class wxVariantDataArrayString: public wxVariantData
1342 {
1343 public:
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
1362 protected:
1363 wxArrayString m_value;
1364
1365 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1366 };
1367
1368 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
1369
1370 bool 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
1380 bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
1381 {
1382 // Not implemented
1383 return false;
1384 }
1385 #endif
1386
1387 bool 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
1403 bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1404 {
1405 // Not implemented
1406 return false;
1407 }
1408 #endif
1409
1410
1411 bool 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
1424 wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1425 {
1426 m_data = new wxVariantDataArrayString(val);
1427 m_name = name;
1428 }
1429
1430 bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1431 {
1432 wxFAIL_MSG( _T("TODO") );
1433
1434 return false;
1435 }
1436
1437 bool wxVariant::operator!=(const wxArrayString& value) const
1438 {
1439 return !(*this == value);
1440 }
1441
1442 void 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
1456 wxArrayString 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
1468 class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
1469 {
1470 DECLARE_DYNAMIC_CLASS(wxVariantDataList)
1471 public:
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
1492 protected:
1493 wxList m_value;
1494 };
1495
1496 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
1497
1498 wxVariantDataList::wxVariantDataList(const wxList& list)
1499 {
1500 SetValue(list);
1501 }
1502
1503 wxVariantDataList::~wxVariantDataList()
1504 {
1505 Clear();
1506 }
1507
1508 void 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
1520 void 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
1532 bool 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
1553 bool 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
1562 bool 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
1580 bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
1581 {
1582 wxFAIL_MSG(wxT("Unimplemented"));
1583 // TODO
1584 return false;
1585 }
1586 #endif
1587
1588 bool wxVariantDataList::Read(wxString& WXUNUSED(str))
1589 {
1590 wxFAIL_MSG(wxT("Unimplemented"));
1591 // TODO
1592 return false;
1593 }
1594
1595 // wxVariant
1596
1597 wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1598 {
1599 m_data = new wxVariantDataList(val);
1600 m_name = name;
1601 }
1602
1603 bool 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
1611 bool wxVariant::operator!= (const wxList& value) const
1612 {
1613 return (!((*this) == value));
1614 }
1615
1616 void 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
1630 wxList& wxVariant::GetList() const
1631 {
1632 wxASSERT( (GetType() == wxT("list")) );
1633
1634 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1635 }
1636
1637 // Make empty list
1638 void wxVariant::NullList()
1639 {
1640 SetData(new wxVariantDataList());
1641 }
1642
1643 // Append to list
1644 void 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
1652 void 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
1660 bool 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
1676 bool 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
1689 void 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
1710 class WXDLLIMPEXP_BASE wxVariantDataStringList: public wxVariantData
1711 {
1712 DECLARE_DYNAMIC_CLASS(wxVariantDataStringList)
1713 public:
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
1731 protected:
1732 wxStringList m_value;
1733 };
1734
1735 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData)
1736
1737 void wxVariantDataStringList::SetValue(const wxStringList& value)
1738 {
1739 m_value = value;
1740 }
1741
1742 bool 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
1763 bool 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
1772 bool 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
1789 bool wxVariantDataStringList::Read(wxSTD istream& WXUNUSED(str))
1790 {
1791 wxFAIL_MSG(wxT("Unimplemented"));
1792 // TODO
1793 return false;
1794 }
1795 #endif
1796
1797 bool 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
1808 wxVariant::wxVariant(const wxStringList& val, const wxString& name)
1809 {
1810 m_data = new wxVariantDataStringList(val);
1811 m_name = name;
1812 }
1813
1814 bool 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
1822 bool 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
1830 void 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
1846 wxStringList& 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
1856 wxVariant 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
1884 wxVariant& 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
1898 size_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
1925 bool 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
1944 bool 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
1972 bool 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
1991 bool 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
2008 bool wxVariant::Convert(wxString* value) const
2009 {
2010 *value = MakeString();
2011 return true;
2012 }
2013
2014 #if wxUSE_DATETIME
2015 bool 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