]> git.saurik.com Git - wxWidgets.git/blob - src/common/variant.cpp
Compile and build fixes for wxGTK and wxMotif
[wxWidgets.git] / src / common / variant.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: variant.cpp
3 // Purpose: wxVariant class, container for any type
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 10/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "variant.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_IOSTREAMH
24 # include <fstream.h>
25 #else
26 # include <fstream>
27 # ifdef _MSC_VER
28 using namespace std;
29 # endif
30 #endif
31
32 #include "wx/stream.h"
33 #include "wx/string.h"
34 #include "wx/variant.h"
35
36 IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
37
38 wxVariant wxNullVariant;
39
40 /*
41 * wxVariantDataList
42 */
43
44 class WXDLLEXPORT wxVariantDataList: public wxVariantData
45 {
46 DECLARE_DYNAMIC_CLASS(wxVariantDataList)
47 public:
48 wxVariantDataList() {}
49 wxVariantDataList(const wxList& list);
50 ~wxVariantDataList();
51
52 wxList& GetValue() const { return (wxList&) m_value; }
53 void SetValue(const wxList& value) ;
54
55 virtual void Copy(wxVariantData& data);
56 virtual bool Eq(wxVariantData& data) const;
57 virtual bool Write(ostream& str) const;
58 virtual bool Write(wxString& str) const;
59 virtual bool Read(istream& str);
60 virtual bool Read(wxString& str);
61 virtual wxString GetType() const { return "list"; };
62
63 void Clear();
64
65 protected:
66 wxList m_value;
67 };
68
69 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
70
71 wxVariantDataList::wxVariantDataList(const wxList& list)
72 {
73 SetValue(list);
74 }
75
76 wxVariantDataList::~wxVariantDataList()
77 {
78 Clear();
79 }
80
81 void wxVariantDataList::SetValue(const wxList& value)
82 {
83 Clear();
84 wxNode* node = value.First();
85 while (node)
86 {
87 wxVariant* var = (wxVariant*) node->Data();
88 m_value.Append(new wxVariant(*var));
89 node = node->Next();
90 }
91 }
92
93 void wxVariantDataList::Clear()
94 {
95 wxNode* node = m_value.First();
96 while (node)
97 {
98 wxVariant* var = (wxVariant*) node->Data();
99 delete var;
100 node = node->Next();
101 }
102 m_value.Clear();
103 }
104
105 void wxVariantDataList::Copy(wxVariantData& data)
106 {
107 wxASSERT_MSG( (data.GetType() == "list"), "wxVariantDataList::Copy: Can't copy to this type of data" );
108
109 wxVariantDataList& listData = (wxVariantDataList&) data;
110
111 listData.Clear();
112 wxNode* node = m_value.First();
113 while (node)
114 {
115 wxVariant* var = (wxVariant*) node->Data();
116 listData.m_value.Append(new wxVariant(*var));
117 node = node->Next();
118 }
119 }
120
121 bool wxVariantDataList::Eq(wxVariantData& data) const
122 {
123 wxASSERT_MSG( (data.GetType() == "list"), "wxVariantDataList::Eq: argument mismatch" );
124
125 wxVariantDataList& listData = (wxVariantDataList&) data;
126 wxNode* node1 = m_value.First();
127 wxNode* node2 = listData.GetValue().First();
128 while (node1 && node2)
129 {
130 wxVariant* var1 = (wxVariant*) node1->Data();
131 wxVariant* var2 = (wxVariant*) node2->Data();
132 if ((*var1) != (*var2))
133 return FALSE;
134 node1 = node1->Next();
135 node2 = node2->Next();
136 }
137 if (node1 || node2) return FALSE;
138 return TRUE;
139 }
140
141 bool wxVariantDataList::Write(ostream& str) const
142 {
143 wxString s;
144 Write(s);
145 str << s;
146 return TRUE;
147 }
148
149 bool wxVariantDataList::Write(wxString& str) const
150 {
151 str = "";
152 wxNode* node = m_value.First();
153 while (node)
154 {
155 wxVariant* var = (wxVariant*) node->Data();
156 if (node != m_value.First())
157 str += " ";
158 wxString str1;
159 str += var->MakeString();
160 node = node->Next();
161 }
162
163 return TRUE;
164 }
165
166 bool wxVariantDataList::Read(istream& WXUNUSED(str))
167 {
168 wxFAIL_MSG("Unimplemented");
169 // TODO
170 return FALSE;
171 }
172
173 bool wxVariantDataList::Read(wxString& WXUNUSED(str))
174 {
175 wxFAIL_MSG("Unimplemented");
176 // TODO
177 return FALSE;
178 }
179
180 /*
181 * wxVariantDataStringList
182 */
183
184 class WXDLLEXPORT wxVariantDataStringList: public wxVariantData
185 {
186 DECLARE_DYNAMIC_CLASS(wxVariantDataStringList)
187 public:
188 wxVariantDataStringList() {}
189 wxVariantDataStringList(const wxStringList& list) { m_value = list; }
190
191 wxStringList& GetValue() const { return (wxStringList&) m_value; }
192 void SetValue(const wxStringList& value);
193
194 virtual void Copy(wxVariantData& data);
195 virtual bool Eq(wxVariantData& data) const;
196 virtual bool Write(ostream& str) const;
197 virtual bool Write(wxString& str) const;
198 virtual bool Read(istream& str);
199 virtual bool Read(wxString& str);
200 virtual wxString GetType() const { return "stringlist"; };
201
202 protected:
203 wxStringList m_value;
204 };
205
206 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData)
207
208 void wxVariantDataStringList::SetValue(const wxStringList& value)
209 {
210 m_value = value;
211 }
212
213 void wxVariantDataStringList::Copy(wxVariantData& data)
214 {
215 wxASSERT_MSG( (data.GetType() == "stringlist"), "wxVariantDataStringList::Copy: Can't copy to this type of data" );
216
217 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
218
219 listData.m_value = m_value ;
220 }
221
222 bool wxVariantDataStringList::Eq(wxVariantData& data) const
223 {
224 wxASSERT_MSG( (data.GetType() == "stringlist"), "wxVariantDataStringList::Eq: argument mismatch" );
225
226 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
227 wxNode* node1 = m_value.First();
228 wxNode* node2 = listData.GetValue().First();
229 while (node1 && node2)
230 {
231 wxString str1 ((char*) node1->Data());
232 wxString str2 ((char*) node2->Data());
233 if (str1 != str2)
234 return FALSE;
235 node1 = node1->Next();
236 node2 = node2->Next();
237 }
238 if (node1 || node2) return FALSE;
239 return TRUE;
240 }
241
242 bool wxVariantDataStringList::Write(ostream& str) const
243 {
244 wxString s;
245 Write(s);
246 str << s;
247 return TRUE;
248 }
249
250 bool wxVariantDataStringList::Write(wxString& str) const
251 {
252 str = "";
253 wxNode* node = m_value.First();
254 while (node)
255 {
256 char* s = (char*) node->Data();
257 if (node != m_value.First())
258 str += " ";
259 str += s;
260 node = node->Next();
261 }
262
263 return TRUE;
264 }
265
266 bool wxVariantDataStringList::Read(istream& WXUNUSED(str))
267 {
268 wxFAIL_MSG("Unimplemented");
269 // TODO
270 return FALSE;
271 }
272
273 bool wxVariantDataStringList::Read(wxString& WXUNUSED(str))
274 {
275 wxFAIL_MSG("Unimplemented");
276 // TODO
277 return FALSE;
278 }
279
280 /*
281 * wxVariantDataLong
282 */
283
284 class WXDLLEXPORT wxVariantDataLong: public wxVariantData
285 {
286 DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
287 public:
288 wxVariantDataLong() { m_value = 0; }
289 wxVariantDataLong(long value) { m_value = value; }
290
291 inline long GetValue() const { return m_value; }
292 inline void SetValue(long value) { m_value = value; }
293
294 virtual void Copy(wxVariantData& data);
295 virtual bool Eq(wxVariantData& data) const;
296 virtual bool Write(ostream& str) const;
297 virtual bool Write(wxString& str) const;
298 virtual bool Write(wxOutputStream &str) const;
299 virtual bool Read(istream& str);
300 virtual bool Read(wxInputStream& str);
301 virtual bool Read(wxString& str);
302 virtual wxString GetType() const { return "long"; };
303
304 protected:
305 long m_value;
306 };
307
308 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
309
310 void wxVariantDataLong::Copy(wxVariantData& data)
311 {
312 wxASSERT_MSG( (data.GetType() == "long"), "wxVariantDataLong::Copy: Can't copy to this type of data" );
313
314 wxVariantDataLong& otherData = (wxVariantDataLong&) data;
315
316 otherData.m_value = m_value;
317 }
318
319 bool wxVariantDataLong::Eq(wxVariantData& data) const
320 {
321 wxASSERT_MSG( (data.GetType() == "long"), "wxVariantDataLong::Eq: argument mismatch" );
322
323 wxVariantDataLong& otherData = (wxVariantDataLong&) data;
324
325 return (otherData.m_value == m_value);
326 }
327
328 bool wxVariantDataLong::Write(ostream& str) const
329 {
330 wxString s;
331 Write(s);
332 str << s;
333 return TRUE;
334 }
335
336 bool wxVariantDataLong::Write(wxOutputStream& str) const
337 {
338 str << m_value;
339 return TRUE;
340 }
341
342 bool wxVariantDataLong::Write(wxString& str) const
343 {
344 str.Printf("%ld", m_value);
345 return TRUE;
346 }
347
348 bool wxVariantDataLong::Read(istream& str)
349 {
350 str >> m_value;
351 return TRUE;
352 }
353
354 bool wxVariantDataLong::Read(wxInputStream& str)
355 {
356 str >> m_value;
357 return TRUE;
358 }
359
360 bool wxVariantDataLong::Read(wxString& str)
361 {
362 m_value = atol((const char*) str);
363 return TRUE;
364 }
365
366 /*
367 * wxVariantDataReal
368 */
369
370 class WXDLLEXPORT wxVariantDataReal: public wxVariantData
371 {
372 DECLARE_DYNAMIC_CLASS(wxVariantDataReal)
373 public:
374 wxVariantDataReal() { m_value = 0.0; }
375 wxVariantDataReal(double value) { m_value = value; }
376
377 inline double GetValue() const { return m_value; }
378 inline void SetValue(double value) { m_value = value; }
379
380 virtual void Copy(wxVariantData& data);
381 virtual bool Eq(wxVariantData& data) const;
382 virtual bool Write(ostream& str) const;
383 virtual bool Write(wxString& str) const;
384 virtual bool Write(wxOutputStream &str) const;
385 virtual bool Read(istream& str);
386 virtual bool Read(wxInputStream& str);
387 virtual bool Read(wxString& str);
388 virtual wxString GetType() const { return "double"; };
389
390 protected:
391 double m_value;
392 };
393
394 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataReal, wxVariantData)
395
396 void wxVariantDataReal::Copy(wxVariantData& data)
397 {
398 wxASSERT_MSG( (data.GetType() == "double"), "wxVariantDataReal::Copy: Can't copy to this type of data" );
399
400 wxVariantDataReal& otherData = (wxVariantDataReal&) data;
401
402 otherData.m_value = m_value;
403 }
404
405 bool wxVariantDataReal::Eq(wxVariantData& data) const
406 {
407 wxASSERT_MSG( (data.GetType() == "double"), "wxVariantDataReal::Eq: argument mismatch" );
408
409 wxVariantDataReal& otherData = (wxVariantDataReal&) data;
410
411 return (otherData.m_value == m_value);
412 }
413
414 bool wxVariantDataReal::Write(ostream& str) const
415 {
416 wxString s;
417 Write(s);
418 str << s;
419 return TRUE;
420 }
421
422 bool wxVariantDataReal::Write(wxOutputStream& str) const
423 {
424 str << m_value;
425 return TRUE;
426 }
427
428 bool wxVariantDataReal::Write(wxString& str) const
429 {
430 str.Printf("%.4f", m_value);
431 return TRUE;
432 }
433
434 bool wxVariantDataReal::Read(istream& str)
435 {
436 str >> m_value;
437 return TRUE;
438 }
439
440 bool wxVariantDataReal::Read(wxInputStream& str)
441 {
442 str >> (float&)m_value;
443 return TRUE;
444 }
445
446 bool wxVariantDataReal::Read(wxString& str)
447 {
448 m_value = atof((const char*) str);
449 return TRUE;
450 }
451
452 /*
453 * wxVariantDataBool
454 */
455
456 class WXDLLEXPORT wxVariantDataBool: public wxVariantData
457 {
458 DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
459 public:
460 wxVariantDataBool() { m_value = 0; }
461 wxVariantDataBool(bool value) { m_value = value; }
462
463 inline bool GetValue() const { return m_value; }
464 inline void SetValue(bool value) { m_value = value; }
465
466 virtual void Copy(wxVariantData& data);
467 virtual bool Eq(wxVariantData& data) const;
468 virtual bool Write(ostream& str) const;
469 virtual bool Write(wxOutputStream& str) const;
470 virtual bool Write(wxString& str) const;
471 virtual bool Read(istream& str);
472 virtual bool Read(wxInputStream& str);
473 virtual bool Read(wxString& str);
474 virtual wxString GetType() const { return "bool"; };
475
476 protected:
477 bool m_value;
478 };
479
480 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
481
482 void wxVariantDataBool::Copy(wxVariantData& data)
483 {
484 wxASSERT_MSG( (data.GetType() == "bool"), "wxVariantDataBool::Copy: Can't copy to this type of data" );
485
486 wxVariantDataBool& otherData = (wxVariantDataBool&) data;
487
488 otherData.m_value = m_value;
489 }
490
491 bool wxVariantDataBool::Eq(wxVariantData& data) const
492 {
493 wxASSERT_MSG( (data.GetType() == "bool"), "wxVariantDataBool::Eq: argument mismatch" );
494
495 wxVariantDataBool& otherData = (wxVariantDataBool&) data;
496
497 return (otherData.m_value == m_value);
498 }
499
500 bool wxVariantDataBool::Write(ostream& str) const
501 {
502 wxString s;
503 Write(s);
504 str << s;
505 return TRUE;
506 }
507
508 bool wxVariantDataBool::Write(wxOutputStream& str) const
509 {
510 str << (char)m_value;
511 return TRUE;
512 }
513
514 bool wxVariantDataBool::Write(wxString& str) const
515 {
516 str.Printf("%d", (int) m_value);
517 return TRUE;
518 }
519
520 bool wxVariantDataBool::Read(istream& WXUNUSED(str))
521 {
522 wxFAIL_MSG("Unimplemented");
523 // str >> (long) m_value;
524 return FALSE;
525 }
526
527 bool wxVariantDataBool::Read(wxInputStream& str)
528 {
529 str >> (char&)m_value;
530 return TRUE;
531 }
532
533 bool wxVariantDataBool::Read(wxString& str)
534 {
535 m_value = (atol((const char*) str) != 0);
536 return TRUE;
537 }
538
539 /*
540 * wxVariantDataChar
541 */
542
543 class WXDLLEXPORT wxVariantDataChar: public wxVariantData
544 {
545 DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
546 public:
547 wxVariantDataChar() { m_value = 0; }
548 wxVariantDataChar(char value) { m_value = value; }
549
550 inline char GetValue() const { return m_value; }
551 inline void SetValue(char value) { m_value = value; }
552
553 virtual void Copy(wxVariantData& data);
554 virtual bool Eq(wxVariantData& data) const;
555 virtual bool Write(ostream& str) const;
556 virtual bool Write(wxOutputStream& str) const;
557 virtual bool Write(wxString& str) const;
558 virtual bool Read(istream& str);
559 virtual bool Read(wxInputStream& str);
560 virtual bool Read(wxString& str);
561 virtual wxString GetType() const { return "char"; };
562
563 protected:
564 char m_value;
565 };
566
567 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
568
569 void wxVariantDataChar::Copy(wxVariantData& data)
570 {
571 wxASSERT_MSG( (data.GetType() == "char"), "wxVariantDataChar::Copy: Can't copy to this type of data" );
572
573 wxVariantDataChar& otherData = (wxVariantDataChar&) data;
574
575 otherData.m_value = m_value;
576 }
577
578 bool wxVariantDataChar::Eq(wxVariantData& data) const
579 {
580 wxASSERT_MSG( (data.GetType() == "char"), "wxVariantDataChar::Eq: argument mismatch" );
581
582 wxVariantDataChar& otherData = (wxVariantDataChar&) data;
583
584 return (otherData.m_value == m_value);
585 }
586
587 bool wxVariantDataChar::Write(ostream& str) const
588 {
589 wxString s;
590 Write(s);
591 str << s;
592 return TRUE;
593 }
594
595 bool wxVariantDataChar::Write(wxOutputStream& str) const
596 {
597 str << m_value;
598 return TRUE;
599 }
600
601 bool wxVariantDataChar::Write(wxString& str) const
602 {
603 str.Printf("%c", m_value);
604 return TRUE;
605 }
606
607 bool wxVariantDataChar::Read(istream& WXUNUSED(str))
608 {
609 wxFAIL_MSG("Unimplemented");
610 // str >> m_value;
611 return FALSE;
612 }
613
614 bool wxVariantDataChar::Read(wxInputStream& str)
615 {
616 str >> m_value;
617 return TRUE;
618 }
619
620 bool wxVariantDataChar::Read(wxString& str)
621 {
622 m_value = str[(size_t)0];
623 return TRUE;
624 }
625
626 /*
627 * wxVariantDataString
628 */
629
630 class WXDLLEXPORT wxVariantDataString: public wxVariantData
631 {
632 DECLARE_DYNAMIC_CLASS(wxVariantDataString)
633 public:
634 wxVariantDataString() { }
635 wxVariantDataString(const wxString& value) { m_value = value; }
636
637 inline wxString GetValue() const { return m_value; }
638 inline void SetValue(const wxString& value) { m_value = value; }
639
640 virtual void Copy(wxVariantData& data);
641 virtual bool Eq(wxVariantData& data) const;
642 virtual bool Write(ostream& str) const;
643 virtual bool Write(wxOutputStream& str) const;
644 virtual bool Write(wxString& str) const;
645 virtual bool Read(istream& str);
646 virtual bool Read(wxInputStream& str);
647 virtual bool Read(wxString& str);
648 virtual wxString GetType() const { return "string"; };
649
650 protected:
651 wxString m_value;
652 };
653
654 void wxVariantDataString::Copy(wxVariantData& data)
655 {
656 wxASSERT_MSG( (data.GetType() == "string"), "wxVariantDataString::Copy: Can't copy to this type of data" );
657
658 wxVariantDataString& otherData = (wxVariantDataString&) data;
659
660 otherData.m_value = m_value;
661 }
662
663 bool wxVariantDataString::Eq(wxVariantData& data) const
664 {
665 wxASSERT_MSG( (data.GetType() == "string"), "wxVariantDataString::Eq: argument mismatch" );
666
667 wxVariantDataString& otherData = (wxVariantDataString&) data;
668
669 return (otherData.m_value == m_value);
670 }
671
672 bool wxVariantDataString::Write(ostream& str) const
673 {
674 str << m_value;
675 return TRUE;
676 }
677
678 bool wxVariantDataString::Write(wxOutputStream& str) const
679 {
680 str << (const char*) m_value;
681 return TRUE;
682 }
683
684 bool wxVariantDataString::Write(wxString& str) const
685 {
686 str = m_value;
687 return TRUE;
688 }
689
690 bool wxVariantDataString::Read(istream& str)
691 {
692 str >> m_value;
693 return TRUE;
694 }
695
696 bool wxVariantDataString::Read(wxInputStream& str)
697 {
698 str >> m_value;
699 return TRUE;
700 }
701
702 bool wxVariantDataString::Read(wxString& str)
703 {
704 m_value = str;
705 return TRUE;
706 }
707
708 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
709
710 /*
711 * wxVariant
712 */
713
714 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
715
716 // Construction & destruction
717 wxVariant::wxVariant()
718 {
719 m_data = (wxVariantData*) NULL;
720 }
721
722 wxVariant::wxVariant(double val)
723 {
724 m_data = new wxVariantDataReal(val);
725 }
726
727 wxVariant::wxVariant(long val)
728 {
729 m_data = new wxVariantDataLong(val);
730 }
731
732 wxVariant::wxVariant(bool val)
733 {
734 m_data = new wxVariantDataBool(val);
735 }
736
737 wxVariant::wxVariant(char val)
738 {
739 m_data = new wxVariantDataChar(val);
740 }
741
742 wxVariant::wxVariant(const wxString& val)
743 {
744 m_data = new wxVariantDataString(val);
745 }
746
747 wxVariant::wxVariant(const char* val)
748 {
749 m_data = new wxVariantDataString(wxString(val));
750 }
751
752 /* Causes ambiguity
753 wxVariant::wxVariant(const wxStringList& val)
754 {
755 m_data = new wxVariantDataStringList(val);
756 }
757 */
758
759 wxVariant::wxVariant(const wxList& val) // List of variants
760 {
761 m_data = new wxVariantDataList(val);
762 }
763
764 wxVariant::wxVariant(const wxVariant& variant)
765 {
766 if (!variant.IsNull())
767 {
768 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
769 variant.m_data->Copy(*m_data);
770 }
771 }
772
773 wxVariant::wxVariant(wxVariantData* data) // User-defined data
774 {
775 m_data = data;
776 }
777
778 wxVariant::~wxVariant()
779 {
780 delete m_data;
781 }
782
783
784 // Make NULL (i.e. delete the data)
785 void wxVariant::MakeNull()
786 {
787 delete m_data;
788 m_data = NULL;
789 }
790
791 // Generic operators
792 // Assignment
793 void wxVariant::operator= (const wxVariant& variant)
794 {
795 if (variant.IsNull())
796 {
797 MakeNull();
798 return;
799 }
800
801 if (IsNull() || (GetType() != variant.GetType()))
802 {
803 if (m_data)
804 delete m_data;
805 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
806 }
807 GetData()->Copy(* variant.GetData());
808 }
809
810 // Assignment using data, e.g.
811 // myVariant = new wxStringVariantData("hello")
812 void wxVariant::operator= (wxVariantData* variantData)
813 {
814 MakeNull();
815 m_data = variantData;
816 }
817
818 bool wxVariant::operator== (const wxVariant& variant) const
819 {
820 if (IsNull() || variant.IsNull())
821 return (IsNull() == variant.IsNull());
822
823 return (GetData()->Eq(* variant.GetData()));
824 }
825
826 bool wxVariant::operator!= (const wxVariant& variant) const
827 {
828 return (!(*this == variant));
829 }
830
831
832 // Specific operators
833 bool wxVariant::operator== (double value) const
834 {
835 double thisValue;
836 if (!Convert(&thisValue))
837 return FALSE;
838 else
839 return (value == thisValue);
840 }
841
842 bool wxVariant::operator!= (double value) const
843 {
844 return (!((*this) == value));
845 }
846
847 void wxVariant::operator= (double value)
848 {
849 if (GetType() == "double")
850 {
851 ((wxVariantDataReal*)GetData())->SetValue(value);
852 }
853 else
854 {
855 if (m_data)
856 delete m_data;
857 m_data = new wxVariantDataReal(value);
858 }
859 }
860
861 bool wxVariant::operator== (long value) const
862 {
863 long thisValue;
864 if (!Convert(&thisValue))
865 return FALSE;
866 else
867 return (value == thisValue);
868 }
869
870 bool wxVariant::operator!= (long value) const
871 {
872 return (!((*this) == value));
873 }
874
875 void wxVariant::operator= (long value)
876 {
877 if (GetType() == "long")
878 {
879 ((wxVariantDataLong*)GetData())->SetValue(value);
880 }
881 else
882 {
883 if (m_data)
884 delete m_data;
885 m_data = new wxVariantDataLong(value);
886 }
887 }
888
889 bool wxVariant::operator== (char value) const
890 {
891 char thisValue;
892 if (!Convert(&thisValue))
893 return FALSE;
894 else
895 return (value == thisValue);
896 }
897
898 bool wxVariant::operator!= (char value) const
899 {
900 return (!((*this) == value));
901 }
902
903 void wxVariant::operator= (char value)
904 {
905 if (GetType() == "char")
906 {
907 ((wxVariantDataChar*)GetData())->SetValue(value);
908 }
909 else
910 {
911 if (m_data)
912 delete m_data;
913 m_data = new wxVariantDataChar(value);
914 }
915 }
916
917 bool wxVariant::operator== (bool value) const
918 {
919 bool thisValue;
920 if (!Convert(&thisValue))
921 return FALSE;
922 else
923 return (value == thisValue);
924 }
925
926 bool wxVariant::operator!= (bool value) const
927 {
928 return (!((*this) == value));
929 }
930
931 void wxVariant::operator= (bool value)
932 {
933 if (GetType() == "bool")
934 {
935 ((wxVariantDataBool*)GetData())->SetValue(value);
936 }
937 else
938 {
939 if (m_data)
940 delete m_data;
941 m_data = new wxVariantDataBool(value);
942 }
943 }
944
945 bool wxVariant::operator== (const wxString& value) const
946 {
947 wxString thisValue;
948 if (!Convert(&thisValue))
949 return FALSE;
950 else
951 return (value == thisValue);
952 }
953
954 bool wxVariant::operator!= (const wxString& value) const
955 {
956 return (!((*this) == value));
957 }
958
959 void wxVariant::operator= (const wxString& value)
960 {
961 if (GetType() == "string")
962 {
963 ((wxVariantDataString*)GetData())->SetValue(value);
964 }
965 else
966 {
967 if (m_data)
968 delete m_data;
969 m_data = new wxVariantDataString(value);
970 }
971 }
972
973 void wxVariant::operator= (const char* value)
974 {
975 if (GetType() == "string")
976 {
977 ((wxVariantDataString*)GetData())->SetValue(wxString(value));
978 }
979 else
980 {
981 if (m_data)
982 delete m_data;
983 m_data = new wxVariantDataString(wxString(value));
984 }
985 }
986
987 bool wxVariant::operator== (const wxStringList& value) const
988 {
989 wxASSERT_MSG( (GetType() == "stringlist"), "Invalid type for == operator" );
990
991 wxVariantDataStringList other(value);
992 return (m_data->Eq(other));
993 }
994
995 bool wxVariant::operator!= (const wxStringList& value) const
996 {
997 return (!((*this) == value));
998 }
999
1000 void wxVariant::operator= (const wxStringList& value)
1001 {
1002 if (GetType() == "stringlist")
1003 {
1004 ((wxVariantDataStringList*)GetData())->SetValue(value);
1005 }
1006 else
1007 {
1008 if (m_data)
1009 delete m_data;
1010 m_data = new wxVariantDataStringList(value);
1011 }
1012 }
1013
1014 bool wxVariant::operator== (const wxList& value) const
1015 {
1016 wxASSERT_MSG( (GetType() == "list"), "Invalid type for == operator" );
1017
1018 wxVariantDataList other(value);
1019 return (m_data->Eq(other));
1020 }
1021
1022 bool wxVariant::operator!= (const wxList& value) const
1023 {
1024 return (!((*this) == value));
1025 }
1026
1027 void wxVariant::operator= (const wxList& value)
1028 {
1029 if (GetType() == "list")
1030 {
1031 ((wxVariantDataList*)GetData())->SetValue(value);
1032 }
1033 else
1034 {
1035 if (m_data)
1036 delete m_data;
1037 m_data = new wxVariantDataList(value);
1038 }
1039 }
1040
1041
1042 // Treat a list variant as an array
1043 wxVariant wxVariant::operator[] (size_t idx) const
1044 {
1045 wxASSERT_MSG( (GetType() == "list" || GetType() == "stringlist"), "Invalid type for array operator" );
1046
1047 if (GetType() == "list")
1048 {
1049 wxVariantDataList* data = (wxVariantDataList*) m_data;
1050 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), "Invalid index for array" );
1051 return * (wxVariant*) (data->GetValue().Nth(idx)->Data());
1052 }
1053 else if (GetType() == "stringlist")
1054 {
1055 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1056 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), "Invalid index for array" );
1057
1058 wxVariant variant( wxString( (char*) (data->GetValue().Nth(idx)->Data()) ));
1059 return variant;
1060 }
1061 return wxNullVariant;
1062 }
1063
1064 wxVariant& wxVariant::operator[] (size_t idx)
1065 {
1066 // We can't return a reference to a variant for a string list, since the string
1067 // is actually stored as a char*, not a variant.
1068
1069 wxASSERT_MSG( (GetType() == "list"), "Invalid type for array operator" );
1070
1071 wxVariantDataList* data = (wxVariantDataList*) m_data;
1072 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), "Invalid index for array" );
1073
1074 return * (wxVariant*) (data->GetValue().Nth(idx)->Data());
1075 }
1076
1077 // Return the number of elements in a list
1078 int wxVariant::GetCount() const
1079 {
1080 wxASSERT_MSG( (GetType() == "list" || GetType() == "stringlist"), "Invalid type for GetCount()" );
1081
1082 if (GetType() == "list")
1083 {
1084 wxVariantDataList* data = (wxVariantDataList*) m_data;
1085 return data->GetValue().Number();
1086 }
1087 else if (GetType() == "stringlist")
1088 {
1089 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1090 return data->GetValue().Number();
1091 }
1092 return 0;
1093 }
1094
1095 wxString wxVariant::MakeString() const
1096 {
1097 if (!IsNull())
1098 {
1099 wxString str;
1100 if (GetData()->Write(str))
1101 return str;
1102 }
1103 return wxString("");
1104 }
1105
1106 // Accessors
1107
1108 void wxVariant::SetData(wxVariantData* data)
1109 {
1110 if (m_data) delete m_data;
1111 m_data = data;
1112 }
1113
1114
1115 // Returns a string representing the type of the variant,
1116 // e.g. "string", "bool", "stringlist", "list", "double", "long"
1117 wxString wxVariant::GetType() const
1118 {
1119 if (IsNull())
1120 return wxString("null");
1121 else
1122 return m_data->GetType();
1123 }
1124
1125
1126 bool wxVariant::IsType(const wxString& type) const
1127 {
1128 return (GetType() == type);
1129 }
1130
1131
1132 // Value accessors
1133 double wxVariant::GetReal() const
1134 {
1135 double value;
1136 if (Convert(& value))
1137 return value;
1138 else
1139 {
1140 wxFAIL_MSG("Could not convert to a real number");
1141 return 0.0;
1142 }
1143 }
1144
1145 long wxVariant::GetInteger() const
1146 {
1147 long value;
1148 if (Convert(& value))
1149 return value;
1150 else
1151 {
1152 wxFAIL_MSG("Could not convert to an integer");
1153 return 0;
1154 }
1155 }
1156
1157 char wxVariant::GetChar() const
1158 {
1159 char value;
1160 if (Convert(& value))
1161 return value;
1162 else
1163 {
1164 wxFAIL_MSG("Could not convert to a char");
1165 return 0;
1166 }
1167 }
1168
1169 bool wxVariant::GetBool() const
1170 {
1171 bool value;
1172 if (Convert(& value))
1173 return value;
1174 else
1175 {
1176 wxFAIL_MSG("Could not convert to a bool");
1177 return 0;
1178 }
1179 }
1180
1181 wxString wxVariant::GetString() const
1182 {
1183 wxString value;
1184 if (Convert(& value))
1185 return value;
1186 else
1187 {
1188 wxFAIL_MSG("Could not convert to a string");
1189 return wxString("");
1190 }
1191 }
1192
1193 wxList& wxVariant::GetList() const
1194 {
1195 wxASSERT( (GetType() == "list") );
1196
1197 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1198 }
1199
1200 wxStringList& wxVariant::GetStringList() const
1201 {
1202 wxASSERT( (GetType() == "stringlist") );
1203
1204 return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
1205 }
1206
1207 // Append to list
1208 void wxVariant::Append(const wxVariant& value)
1209 {
1210 wxList& list = GetList();
1211
1212 list.Append(new wxVariant(value));
1213 }
1214
1215 // Insert at front of list
1216 void wxVariant::Insert(const wxVariant& value)
1217 {
1218 wxList& list = GetList();
1219
1220 list.Insert(new wxVariant(value));
1221 }
1222
1223 // Returns TRUE if the variant is a member of the list
1224 bool wxVariant::Member(const wxVariant& value) const
1225 {
1226 wxList& list = GetList();
1227
1228 wxNode* node = list.First();
1229 while (node)
1230 {
1231 wxVariant* other = (wxVariant*) node->Data();
1232 if (value == *other)
1233 return TRUE;
1234 node = node->Next();
1235 }
1236 return FALSE;
1237 }
1238
1239 // Deletes the nth element of the list
1240 bool wxVariant::Delete(int item)
1241 {
1242 wxList& list = GetList();
1243
1244 wxASSERT_MSG( (item < list.Number()), "Invalid index to Delete" );
1245 wxNode* node = list.Nth(item);
1246 wxVariant* variant = (wxVariant*) node->Data();
1247 delete variant;
1248 delete node;
1249 return TRUE;
1250 }
1251
1252 // Clear list
1253 void wxVariant::ClearList()
1254 {
1255 if (!IsNull() && (GetType() == "list"))
1256 {
1257 ((wxVariantDataList*) m_data)->Clear();
1258 }
1259 else
1260 {
1261 if (GetType() != "list")
1262 {
1263 delete m_data;
1264 m_data = NULL;
1265 }
1266 m_data = new wxVariantDataList;
1267 }
1268 }
1269
1270 // Type conversion
1271 bool wxVariant::Convert(long* value) const
1272 {
1273 wxString type(GetType());
1274 if (type == "double")
1275 *value = (long) (((wxVariantDataReal*)GetData())->GetValue());
1276 else if (type == "long")
1277 *value = ((wxVariantDataLong*)GetData())->GetValue();
1278 else if (type == "bool")
1279 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
1280 else if (type == "string")
1281 *value = atol((const char*) ((wxVariantDataString*)GetData())->GetValue());
1282 else
1283 return FALSE;
1284
1285 return TRUE;
1286 }
1287
1288 bool wxVariant::Convert(bool* value) const
1289 {
1290 wxString type(GetType());
1291 if (type == "double")
1292 *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0);
1293 else if (type == "long")
1294 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
1295 else if (type == "bool")
1296 *value = ((wxVariantDataBool*)GetData())->GetValue();
1297 else if (type == "string")
1298 {
1299 wxString val(((wxVariantDataString*)GetData())->GetValue());
1300 val.MakeLower();
1301 if (val == "true" || val == "yes")
1302 *value = TRUE;
1303 else if (val == "false" || val == "no")
1304 *value = FALSE;
1305 else
1306 return FALSE;
1307 }
1308 else
1309 return FALSE;
1310
1311 return TRUE;
1312 }
1313
1314 bool wxVariant::Convert(double* value) const
1315 {
1316 wxString type(GetType());
1317 if (type == "double")
1318 *value = ((wxVariantDataReal*)GetData())->GetValue();
1319 else if (type == "long")
1320 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
1321 else if (type == "bool")
1322 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
1323 else if (type == "string")
1324 *value = (double) atof((const char*) ((wxVariantDataString*)GetData())->GetValue());
1325 else
1326 return FALSE;
1327
1328 return TRUE;
1329 }
1330
1331 bool wxVariant::Convert(char* value) const
1332 {
1333 wxString type(GetType());
1334 if (type == "char")
1335 *value = ((wxVariantDataChar*)GetData())->GetValue();
1336 else if (type == "long")
1337 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
1338 else if (type == "bool")
1339 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
1340 else
1341 return FALSE;
1342
1343 return TRUE;
1344 }
1345
1346 bool wxVariant::Convert(wxString* value) const
1347 {
1348 *value = MakeString();
1349 return TRUE;
1350 }
1351