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