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