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