]> git.saurik.com Git - wxWidgets.git/blame - src/common/variant.cpp
fix for private access for wxTimerProc
[wxWidgets.git] / src / common / variant.cpp
CommitLineData
341287bf
JS
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
fbc535ff 23#if wxUSE_IOSTREAMH
03f38c58 24# include <fstream.h>
fbc535ff 25#else
03f38c58
VZ
26# include <fstream>
27# ifdef _MSC_VER
28 using namespace std;
29# endif
fbc535ff 30#endif
341287bf
JS
31
32#include "wx/string.h"
33#include "wx/variant.h"
34
35IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
36
37wxVariant wxNullVariant;
38
39/*
40 * wxVariantDataList
41 */
42
43class WXDLLEXPORT wxVariantDataList: public wxVariantData
44{
45DECLARE_DYNAMIC_CLASS(wxVariantDataList)
46public:
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
64protected:
65 wxList m_value;
66};
67
68IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
69
70wxVariantDataList::wxVariantDataList(const wxList& list)
71{
72 SetValue(list);
73}
74
75wxVariantDataList::~wxVariantDataList()
76{
77 Clear();
78}
79
80void 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
92void 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
104void 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
120bool 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
140bool wxVariantDataList::Write(ostream& str) const
141{
142 wxString s;
143 Write(s);
144 str << s;
145 return TRUE;
146}
147
148bool 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
165bool wxVariantDataList::Read(istream& WXUNUSED(str))
166{
167 wxFAIL_MSG("Unimplemented");
168 // TODO
169 return FALSE;
170}
171
172bool wxVariantDataList::Read(wxString& WXUNUSED(str))
173{
174 wxFAIL_MSG("Unimplemented");
175 // TODO
176 return FALSE;
177}
178
179/*
180 * wxVariantDataStringList
181 */
182
183class WXDLLEXPORT wxVariantDataStringList: public wxVariantData
184{
185DECLARE_DYNAMIC_CLASS(wxVariantDataStringList)
186public:
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
201protected:
202 wxStringList m_value;
203};
204
205IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData)
206
207void wxVariantDataStringList::SetValue(const wxStringList& value)
208{
209 m_value = value;
210}
211
212void 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
221bool 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
241bool wxVariantDataStringList::Write(ostream& str) const
242{
243 wxString s;
244 Write(s);
245 str << s;
246 return TRUE;
247}
248
249bool 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
265bool wxVariantDataStringList::Read(istream& WXUNUSED(str))
266{
267 wxFAIL_MSG("Unimplemented");
268 // TODO
269 return FALSE;
270}
271
272bool wxVariantDataStringList::Read(wxString& WXUNUSED(str))
273{
274 wxFAIL_MSG("Unimplemented");
275 // TODO
276 return FALSE;
277}
278
279/*
280 * wxVariantDataLong
281 */
282
283class WXDLLEXPORT wxVariantDataLong: public wxVariantData
284{
285DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
286public:
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
301protected:
302 long m_value;
303};
304
305IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
306
307void 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
316bool 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
325bool wxVariantDataLong::Write(ostream& str) const
326{
327 wxString s;
328 Write(s);
329 str << s;
330 return TRUE;
331}
332
333bool wxVariantDataLong::Write(wxString& str) const
334{
335 str.Printf("%ld", m_value);
336 return TRUE;
337}
338
339bool wxVariantDataLong::Read(istream& str)
340{
341 str >> m_value;
342 return TRUE;
343}
344
345bool wxVariantDataLong::Read(wxString& str)
346{
347 m_value = atol((const char*) str);
348 return TRUE;
349}
350
351/*
352 * wxVariantDataReal
353 */
354
355class WXDLLEXPORT wxVariantDataReal: public wxVariantData
356{
357DECLARE_DYNAMIC_CLASS(wxVariantDataReal)
358public:
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
373protected:
374 double m_value;
375};
376
377IMPLEMENT_DYNAMIC_CLASS(wxVariantDataReal, wxVariantData)
378
379void 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
388bool 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
397bool wxVariantDataReal::Write(ostream& str) const
398{
399 wxString s;
400 Write(s);
401 str << s;
402 return TRUE;
403}
404
405bool wxVariantDataReal::Write(wxString& str) const
406{
407 str.Printf("%.4f", m_value);
408 return TRUE;
409}
410
411bool wxVariantDataReal::Read(istream& str)
412{
413 str >> m_value;
414 return TRUE;
415}
416
417bool wxVariantDataReal::Read(wxString& str)
418{
419 m_value = atof((const char*) str);
420 return TRUE;
421}
422
423/*
424 * wxVariantDataBool
425 */
426
427class WXDLLEXPORT wxVariantDataBool: public wxVariantData
428{
429DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
430public:
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
445protected:
446 bool m_value;
447};
448
449IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
450
451void 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
460bool 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
469bool wxVariantDataBool::Write(ostream& str) const
470{
471 wxString s;
472 Write(s);
473 str << s;
474 return TRUE;
475}
476
477bool wxVariantDataBool::Write(wxString& str) const
478{
479 str.Printf("%d", (int) m_value);
480 return TRUE;
481}
482
483bool wxVariantDataBool::Read(istream& WXUNUSED(str))
484{
485 wxFAIL_MSG("Unimplemented");
486// str >> (long) m_value;
487 return FALSE;
488}
489
490bool wxVariantDataBool::Read(wxString& str)
491{
492 m_value = (atol((const char*) str) != 0);
493 return TRUE;
494}
495
496/*
497 * wxVariantDataChar
498 */
499
500class WXDLLEXPORT wxVariantDataChar: public wxVariantData
501{
502DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
503public:
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
518protected:
519 char m_value;
520};
521
522IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
523
524void 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
533bool 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
542bool wxVariantDataChar::Write(ostream& str) const
543{
544 wxString s;
545 Write(s);
546 str << s;
547 return TRUE;
548}
549
550bool wxVariantDataChar::Write(wxString& str) const
551{
552 str.Printf("%c", m_value);
553 return TRUE;
554}
555
556bool wxVariantDataChar::Read(istream& WXUNUSED(str))
557{
558 wxFAIL_MSG("Unimplemented");
559// str >> m_value;
560 return FALSE;
561}
562
563bool wxVariantDataChar::Read(wxString& str)
564{
565 m_value = str[(size_t)0];
566 return TRUE;
567}
568
569/*
570 * wxVariantDataString
571 */
572
573class WXDLLEXPORT wxVariantDataString: public wxVariantData
574{
575DECLARE_DYNAMIC_CLASS(wxVariantDataString)
576public:
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
591protected:
592 wxString m_value;
593};
594
595void 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
604bool 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
613bool wxVariantDataString::Write(ostream& str) const
614{
615 str << m_value;
616 return TRUE;
617}
618
619bool wxVariantDataString::Write(wxString& str) const
620{
621 str = m_value;
622 return TRUE;
623}
624
625bool wxVariantDataString::Read(istream& str)
626{
627 str >> m_value;
628 return TRUE;
629}
630
631bool wxVariantDataString::Read(wxString& str)
632{
633 m_value = str;
634 return TRUE;
635}
636
637IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
638
639/*
640 * wxVariant
641 */
642
643IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
644
645// Construction & destruction
646wxVariant::wxVariant()
647{
648 m_data = (wxVariantData*) NULL;
649}
650
651wxVariant::wxVariant(double val)
652{
653 m_data = new wxVariantDataReal(val);
654}
655
656wxVariant::wxVariant(long val)
657{
658 m_data = new wxVariantDataLong(val);
659}
660
661wxVariant::wxVariant(bool val)
662{
663 m_data = new wxVariantDataBool(val);
664}
665
666wxVariant::wxVariant(char val)
667{
668 m_data = new wxVariantDataChar(val);
669}
670
671wxVariant::wxVariant(const wxString& val)
672{
673 m_data = new wxVariantDataString(val);
674}
675
676wxVariant::wxVariant(const char* val)
677{
678 m_data = new wxVariantDataString(wxString(val));
679}
680
681/* Causes ambiguity
682wxVariant::wxVariant(const wxStringList& val)
683{
684 m_data = new wxVariantDataStringList(val);
685}
686*/
687
688wxVariant::wxVariant(const wxList& val) // List of variants
689{
690 m_data = new wxVariantDataList(val);
691}
692
693wxVariant::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
702wxVariant::wxVariant(wxVariantData* data) // User-defined data
703{
704 m_data = data;
705}
706
707wxVariant::~wxVariant()
708{
709 delete m_data;
710}
711
712
713// Make NULL (i.e. delete the data)
714void wxVariant::MakeNull()
715{
716 delete m_data;
717 m_data = NULL;
718}
719
720// Generic operators
721// Assignment
722void 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")
741void wxVariant::operator= (wxVariantData* variantData)
742{
743 MakeNull();
744 m_data = variantData;
745}
746
747bool 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
755bool wxVariant::operator!= (const wxVariant& variant) const
756{
757 return (!(*this == variant));
758}
759
760
761// Specific operators
762bool wxVariant::operator== (double value) const
763{
764 double thisValue;
765 if (!Convert(&thisValue))
766 return FALSE;
767 else
768 return (value == thisValue);
769}
770
771bool wxVariant::operator!= (double value) const
772{
773 return (!((*this) == value));
774}
775
776void 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
790bool wxVariant::operator== (long value) const
791{
792 long thisValue;
793 if (!Convert(&thisValue))
794 return FALSE;
795 else
796 return (value == thisValue);
797}
798
799bool wxVariant::operator!= (long value) const
800{
801 return (!((*this) == value));
802}
803
804void 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
818bool wxVariant::operator== (char value) const
819{
820 char thisValue;
821 if (!Convert(&thisValue))
822 return FALSE;
823 else
824 return (value == thisValue);
825}
826
827bool wxVariant::operator!= (char value) const
828{
829 return (!((*this) == value));
830}
831
832void 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
846bool wxVariant::operator== (bool value) const
847{
848 bool thisValue;
849 if (!Convert(&thisValue))
850 return FALSE;
851 else
852 return (value == thisValue);
853}
854
855bool wxVariant::operator!= (bool value) const
856{
857 return (!((*this) == value));
858}
859
860void 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
874bool 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
883bool wxVariant::operator!= (const wxString& value) const
884{
885 return (!((*this) == value));
886}
887
888void 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
902void 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
916bool 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
924bool wxVariant::operator!= (const wxStringList& value) const
925{
926 return (!((*this) == value));
927}
928
929void 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
943bool 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
951bool wxVariant::operator!= (const wxList& value) const
952{
953 return (!((*this) == value));
954}
955
956void 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
972wxVariant 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
993wxVariant& 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
1007int 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
1024wxString 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
1037void 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"
1046wxString wxVariant::GetType() const
1047{
1048 if (IsNull())
1049 return wxString("null");
1050 else
1051 return m_data->GetType();
1052}
1053
1054
1055bool wxVariant::IsType(const wxString& type) const
1056{
1057 return (GetType() == type);
1058}
1059
1060
1061// Value accessors
1062double 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
1074long 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
1086char 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
1098bool 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
1110wxString 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
1122wxList& wxVariant::GetList() const
1123{
1124 wxASSERT( (GetType() == "list") );
1125
1126 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1127}
1128
1129wxStringList& wxVariant::GetStringList() const
1130{
1131 wxASSERT( (GetType() == "stringlist") );
1132
1133 return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
1134}
1135
1136// Append to list
1137void 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
1145void 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
1153bool 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
1169bool 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
1182void 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
1200bool 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
1217bool 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
1243bool 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
1260bool 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
1275bool wxVariant::Convert(wxString* value) const
1276{
1277 *value = MakeString();
1278 return TRUE;
1279}
1280