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