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