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