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