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