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