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