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