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